Click to See Complete Forum and Search --> : [2.0] Abstract class must implement interface?
DNA7433
Aug 14th, 2006, 01:17 AM
Hey everyone,
I have an abstract class that implements a few methods of an interface, but not all. I want the derived classes to implement the rest. When I build the project it says 'MyClass' does not implement interface member 'MyIFace.Method()'. The names have been changed of course to protect the identity of my application :D. Why should an abstract class be forced to implement all members of an interface when it can't be instantiated anyways? I thought this used to work in earlier versions of .NET?
Thanks in advance
jmcilhinney
Aug 14th, 2006, 01:54 AM
Classes cannot pick and choose which methods of an interface they want to implement. It's all or nothing. Note that if ClassA implements InterfaceA and ClassB inherits ClassA, there is no obligation on ClassB to implement any of the members of InterfaceA. That means that if ClassA is not forced to implement every member of InterfaceA then there's no guarantee that the neglected members will ever be implemented. All you need to do is declare the interface members that you don't want to implement in the base class as abstract.public interface InterfaceA
{
void MethodA();
void MethodB();
}
public abstract class ClassA : InterfaceA
{
// Base class provides a non-empty implementation.
public void MethodA()
{
}
// Base class provides an empty implementation.
// Derived class must provide a non-empty implementation.
public abstract void MethodB();
}
public class ClassB : ClassA
{
// Derived class provides a non-empty implementation.
public override void MethodB()
{
}
}
DNA7433
Aug 14th, 2006, 02:05 AM
Hmm, I thought I had tried the method you posted but apparently I had not. It works, thanks!
But...it still doesn't make sense. If a class says it implements an interface, why would a derived class not be under the same constraint? That's gotta break some academic definition of inheritance. In your example, if ClassA didn't define an abstract MethodB(), why would that responsibility not fall on ClassB? There's no possible way to instantiate ClassA so why should a defnition of MethodB() be forced upon ClassA?
jmcilhinney
Aug 14th, 2006, 02:38 AM
It makes complete sense. If a class implements an interface then it promises to implement every member of that interface. Even if you can't create an instance of ClassA directly you can still have instances of that class. Extending the example above, you can do this:ClassB obj1 = new ClassB();
obj1.MethodB();
ClassA obj2 = (ClassA)obj1;
obj2.MethodB(); // ***
InterfaceA obj3 = (InterfaceA)obj2;
obj3.MethodB();If you were allowed to do as you want and not provide an implementation of MethodB in ClassA, the line I've marked with the asterisks would be illegal because ClassA would have no MethodB. Now that wouldn't make sense.
DNA7433
Aug 14th, 2006, 03:26 PM
No, the line would still make sense. ClassA has promised to implement the whole interface, it's just deferring parts of that implementation to derived classes. It shouldn't matter if ClassA redefines all the methods from InterfaceA (whether as abstract or not). In the line that you starred and also the last line, that's where polymorphism takes over.
What do you have to say about the last two lines? All .NET has to go on is InterfaceA and it needs to invoke the most-derived implementation of MethodB. It doesn't know what the real type of object the reference refers to (well it does but that's because .NET is smart), but the point is it could be a ClassB, or some other class that implements InterfaceA. Who cares if ClassA provides an implementation or not?
When ClassB decides to derive ClassA, it also agrees to support InterfaceA.
jmcilhinney
Aug 14th, 2006, 06:07 PM
No, the line would still make sense.You what? How can you call a method that doesn't exist? Either ClassA has a method or it doesn't. You could implement things the way you're suggesting but that would simply muddy the waters. You'd have to add to the documentation that you can call these members of ClassA even though those members of ClassA don't exist. Frankly, makes no sense at all. Also, how would inheritors know that they it was their responsibility to implement those methods? You would have to have something in the base class to tell them so. What do you know? That's exactly what declaring a member abstract does.
When ClassB decides to derive ClassA, it also agrees to support InterfaceA.No it doesn't. You may think that it should be because that would be convenient for you, but it isn't. There is no explicit connection between the interface and the derived class whatsoever. ClassB inherits ClassA and that's all. ClassB inherits the members of InterfaceA that ClassA has implemented and you're trying to artificially extend that to encompass ClassB too, but it doesn't. I challenge you to find any documentation that says that it does. This is from the MSDN help topic entitled
"Interfaces Overview":An interface represents a contract, in that a class that implements an interface must implement every aspect of that interface exactly as it is defined.That's fairly explicit. That's the way things work. Of course, they could have been implemented differently but they weren't. The current implementation is completely logical. What you're suggesting, while convenient in some instances, is not logical. If you want a platform that behaves differently then you're obviously welcome to create your own.
MasterBlaster
Aug 14th, 2006, 06:35 PM
Classes cannot pick and choose which methods of an interface they want to implement. It's all or nothing. Note that if ClassA implements InterfaceA and ClassB inherits ClassA, there is no obligation on ClassB to implement any of the members of InterfaceA.
That is because ClassA already Implements that interface so ClassB automatically implements because it is a derived from classA. You should move the Declaration of your interface to your Derived class. Then you can partially implement the interface in ClassA and implement the rest of it in ClassB.
As jmcilhinney already properly stated, there is no guarentee to the compiler that a derived class will ever implement the rest of the interface. That is the whole point of using Interfaces. However, I wouldn't create abstract methods to comply with an interface. You will not receive a compile error if you forget to override the abstract method.
jmcilhinney
Aug 14th, 2006, 07:16 PM
You will not receive a compile error if you forget to override the abstract method.That's not true. See the screenshot below. If you make the derived classes implement the interface directly instead of the base class then you're defeating the purpose of inheritance. Implement the interface in the base class and provide abstract declarations of the members you don't want to implement. That's the "proper" way to do this. The whole point of an abstract member is to say "I'm not going to implement this member but I'm going to guarantee that all my descendants do". That is EXACTLY what you want, so that is EXACTLY what you should do.
DNA7433
Aug 15th, 2006, 02:12 AM
I understand your argument, but I see it more as "here is how .NET works" rather than "academically, this is how OOP works."
You what? How can you call a method that doesn't exist? Either ClassA has a method or it doesn't. You could implement things the way you're suggesting but that would simply muddy the waters. You'd have to add to the documentation that you can call these members of ClassA even though those members of ClassA don't exist. Frankly, makes no sense at all. Also, how would inheritors know that they it was their responsibility to implement those methods? You would have to have something in the base class to tell them so. What do you know? That's exactly what declaring a member abstract does.The method most certainly does exist. ClassA doesn't have the method, but it's abstract so no one can possibly instantiate it, which leaves ALL POSSIBLE derived classes to pick up the tab. EVERY possible scenario is covered. ClassA must be extended and all derived classes must finish the implementation of the interface. There will be an implementation of that method somewhere in the hierarchy, and I would say that still fits with the definition of an interface contract. All that's needed is a compiler message saying the interface isn't full implemented in concrete ClassB.
No it doesn't. You may think that it should be because that would be convenient for you, but it isn't. There is no explicit connection between the interface and the derived class whatsoever. ClassB inherits ClassA and that's all. ClassB inherits the members of InterfaceA that ClassA has implemented and you're trying to artificially extend that to encompass ClassB too, but it doesn't. I challenge you to find any documentation that says that it does. This is from the MSDN help topic entitled
"Interfaces Overview":An interface represents a contract, in that a class that implements an interface must implement every aspect of that interface exactly as it is defined.Ok, so .NET isn't as flexible as I had hoped.
An interface represents a contract, in that a class that implements an interface must implement every aspect of that interface exactly as it is defined. That's fairly explicit. That's the way things work. Of course, they could have been implemented differently but they weren't. The current implementation is completely logical. What you're suggesting, while convenient in some instances, is not logical. If you want a platform that behaves differently then you're obviously welcome to create your own.I don't know that that's explicit in there. It does say that the implementation must implement every aspect exactly as it's defined. So for example you can't change a parameter from List<> to IEnumerable<> or vice versa. But we're not talking about that.
The whole point of an abstract member is to say "I'm not going to implement this member but I'm going to guarantee that all my descendants do".In C++ there are no interfaces, only classes with all abstract members. That's what an interface is. It says that I don't have an implementation for any of these, but I'll garuantee that anyone who implements me will. And it doesn't matter how big the class hierarchy is...as long as all the concrete classes have a definition for the interface members. Again, I still don't see why an abstract class should be required to supply an abstract definition for a member declared in an interface that it doesn't want to implement. There are definitely going to be derived classes in that case...make them implement the method!
MasterBlaster
Aug 15th, 2006, 10:40 AM
That's not true. See the screenshot below. If you make the derived classes implement the interface directly instead of the base class then you're defeating the purpose of inheritance. Implement the interface in the base class and provide abstract declarations of the members you don't want to implement. That's the "proper" way to do this. The whole point of an abstract member is to say "I'm not going to implement this member but I'm going to guarantee that all my descendants do". That is EXACTLY what you want, so that is EXACTLY what you should do.
Badass man! I didn't realize that it would still break during a build. I thought I rememberd trying that an it not throwing a compiler error. I've never run across it if I use interfaces in abstrace classes I usually force my abstract classes to implement every method any way. Never had a need to do it the other way. Thanks man! :thumb:
CornedBee
Aug 15th, 2006, 10:53 AM
Just to throw a little oil on the fire, Java behaves exactly as the OP expected C# to behave. An abstract class there is under no obligation to implement all functions of all interfaces it claims to implement. If it doesn't, then further derived classes have to.
C# is merely making this requirement explicit.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.