Need help understanding abstract classes that implement an interface - c#

Consider the following example. I have an interface MyInterface, and then two abstract classes MyAbstractClass1 and MyAbstractClass2. MyAbstractClass1 implements MyInterface, but MyAbstractClass2 does not.
Now I have three concrete classes.
MyConcreteClass1 is derived from MyAbstractClass1 but does not implement MyInterface.
MyConcreteClass2 is derived from MyAbstractClass2, but does implement MyInterface.
MyConcreteClass3 is derived from MyAbstractClass1, and does implement MyInterface.
Does ConcreteClass1 also implicitly implement MyInterface because it derives from MyAbstractClass1? Assuming MyAbstractClass1 implements the methods of MyInteface implicitly then ConcreteClass1 should not have to be cast to a MyInterface to access the MyInteface methods right?
MyAbstractClass1 can implicitly implement a method of MyInterface as an abstract method, but can't explicitly implement a method of MyInterface as an abstract method. Why is this?
Is MyConcreteClass3 excessive because it's implementing an interface that is already implemented by its base class? Would there be a reason you would want to do that even if you knew all classes that derive from MyAbstractClass1 should also implement MyInterface.
Here's a class diagram
alt text http://files.getdropbox.com/u/113068/abstractclassesandinterfaces.png
Here's the code:
//interface
public interface MyInterface
{
void MyMethodA();
void MyMethodB();
void MyMethodC();
}
//abstract classes
public abstract class MyAbstractClass1 : MyInterface
{
public void MyMethodA()
{
}
void MyInterface.MyMethodB()
{
}
//Error: "the modifier abstract is not valid for this item"
//abstract void MyInterface.MyMethodC();
//This works
public abstract void MyMethodC();
public abstract void MyMethodZ();
}
public abstract class MyAbstractClass2
{
public void MyMethodX()
{
}
public abstract void MyMethodY();
}
//Concrete classes
//ConcreteClass 1: Only Abstract class implements the interface
public class ConcreteClass1 : MyAbstractClass1
{
public override void MyMethodC()
{
}
public override void MyMethodZ()
{
}
}
//ConcreteClass 1: Only Concrete class implements the interface
public class ConcreteClass2 : MyAbstractClass2, MyInterface
{
public override void MyMethodY()
{
}
public void MyMethodA()
{
}
public void MyMethodB()
{
}
public void MyMethodC()
{
}
}
//ConcreteClass 1: Both concrete and abstract class implement the interface
public class ConcreteClass3 : MyAbstractClass1, MyInterface
{
public override void MyMethodC()
{
}
public override void MyMethodZ()
{
}
}

Does ConcreteClass1 also implicitly implement MyInterface because it derives from MyAbstractClass1?
Yes.
ConcreteClass1 should not have to be cast to a MyInterface to access the MyInteface methods right?
Correct. (myConcreteClass1 is MyInterface) will evaluate true.
MyAbstractClass1 can implicitly implement a method of MyInterface as an abstract method, but can't explicitly implement a method of MyInterface as an abstract method.
Explicit implementation is to distinguish between overlapping member signatures. The explicit implementation is private to the class you are implementing it on, so it is not accessible to derived classes (and thus cannot be abstract). You also cannot force classes which derive from MyAbstractClass1 to explicitly implement MyInterface, so there is no way to ensure the abstract member will ever be implemented.
Is MyConcreteClass3 excessive because it's implementing an interface that is already implemented by its base class? Would there be a reason you would want to do that even if you knew all classes that derive from MyAbstractClass1 should also implement MyInterface.
Not necessarily, If you need to explicitly implement a member of the interface to distinguish it from an overlapping member on MyConcreteClass3. Otherwise it is unnecessary.

In this case, all three classes implement the interface (directly or indirectly). This is because MyAbstractClass1 implements MyInterface, and since MyConcreteClass1 derives from MyAbstractClass1, it also follows that you can treat MyConcreteClass1 as a MyInterface. MyConcreteClass2 can be treated with something that derives from MyAbstractClass1, as long as you treat it as a MyInterface. the derivation from MyInterface in ConcreteClass3 is a bit redundant since MyAbstractClass1 already implements MyInterface.
With all of that information, i'd say that yes, it is redundant to implement MyInterface on MyConcreteClass3 since it derives from MyAbstractClass1 which already implements MyInterface.
I think the reason that you cant have an abstract implementation of an interface method is that it provides no code itself and you cannot guarantee that it will be overriden in subcalsses. Use Virtual instead.

It's not redundant. Consider this class setup to simplify ...
public interface I
{
void A();
}
public abstract class B : I
{
public void A( )
{
Console.WriteLine("Base");
}
}
public class D : B
{
public void A()
{
Console.WriteLine("Hide");
}
}
public class U
{
public void M(I i)
{
Console.WriteLine("M!");
}
}
Executing this ...
var d = new D();
var i = (I)d;
var u = new U();
i.A();
d.A();
u.M(d);
u.M(i);
You will get ...
Base
Hide
M!
M!
If you add the interface from the derived class ...
public class D : B, I
{
public void A()
{
Console.WriteLine("Hide");
}
}
You will get ...
Hide
Hide
M!
M!
So, it effects which implementation of the interface method you get when you get the Iness of your derived class.

Related

C# interface implementation with derived interface

In the following sample class "SomeClass" does not implement "ISomeInterface". Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
namespace Test
{
public interface IBaseInterface
{
void DoBaseStuff();
}
public interface IChildInterface : IBaseInterface
{
void DoChildStuff();
}
public interface ISomeInterface
{
void DoSomething(IBaseInterface baseInterface);
}
public class SomeClass : ISomeInterface
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
}
This restriction exists because the ISomeInterface expects that any IBaseInterface will satisfy the contract. That is, if you have the following:
public interface IBase {}
public interface IChildA : IBase {}
public interface IChildB : IBase {}
And an interface that expects IBase:
public interface IFoo { void Bar(IBase val); }
Then restricting this in a derived class as you would like:
public class Foo : IFoo { public void Bar(IChildA val) {} }
Would create the following problem:
IChildB something = new ChildB();
IFoo something = new Foo();
something.Bar(something); // This is an invalid call
As such, you're not implementing the contract you said you would.
In this situation, you have two simple options:
Adjust IFoo to be generic, and accept a T that is a derivation of IBase:
public interface IFoo<T> where T : IBase { void Bar(T val); }
public class Foo : IFoo<IChildA> { public void Bar(IChildA val) {} }
Of course, this means that Foo can no longer accept any IBase (including IChildB).
Adjust Foo to implement IFoo, with an additional utility method for void Bar(IChildA val):
public class Foo : IFoo
{
public void Bar(IBase val) {}
public void Bar(IChildA val) {}
}
This has an interesting side-effect: whenever you call ((IFoo)foo).Bar it will expect IBase, and when you call foo.Bar it will expect IChildA or IBase. This means it satisfies the contract, while also having your derived-interface-specific method. If you want to "hide" the Bar(IBase) method more, you could implement IFoo explicitly:
void IFoo.Bar(IBase val) { }
This creates even more inconsistent behavior in your code, as now ((IFoo)foo).Bar is completely different from foo.Bar, but I leave the decision up to you.
This means, with the second version in this section, that foo.Bar(new ChildB()); is now invalid, as IChildB is not an IChildA.
Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
This is not allowed because of the reasoning I mentioned above, IFoo.Bar expects any IBase, whereas you want to further constrain the type to IChildA, which is not a super-interface of IBase, and even if it were it would not be allowed because it violates the interface implementation, though you could more easily define a second method at that point that does what you want.
Keep in mind that when you implement an interface, you subscribe to a contract, and C# will not let you violate that contract.
This violates the Liskov substitution principle.
ISomeInterface guarantees that the method can be called with any IBaseInterface instance. Your implementation cannot limit that to only accept IChildInterface interfaces.
From MSDN:
When a class or struct implements an interface, the class or struct must provide an implementation for all of the members that the interface defines
This method in the derived
void DoSomething(IChildInterface baseInterface)
Does not have the same signature as the one in the interface:
void DoSomething(IBaseInterface baseInterface)
IChildInterface and IBaseInterface are not the same types. Therefore your derived class does not implement all methods of the interface and you get the compilation error.
For a possible the logic behind having this as a restriction instead of the compiler understanding the inheritance see Liskov's substitution principle as in SLakes answer
You should change some interface to use some type which implements IBaseInterface,
then change the method signatures to use whichever child your SomeClass wants.
public interface ISomeInterface<TSomeChild> where TSomeChild : IBaseInterface
{
void DoSomething(TSomeChild baseInterface);
}
public class SomeClass : ISomeInterface<IChildInterface>
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
If you could do that, then you could do this:
IAnimal cat = new Cat();
IAnimalTrainer dogTrainer = new DogTrainer();
dogTrainer.Train(cat);
An IAnimalTrainer can train any IAnimal. But a DogTrainer can only train Dogs. Thus it's illegal for DogTrainer to implement the IAnimalTrainer interface.

C# Deriving a class from more than one abstract class

I created two abstract classes and tried to create a class that inherits from both. But I get an error message.
abstract class AbstractClassOne
{
public abstract void ShowMessage();
public abstract void DisplayName();
}
abstract class AbstractClassTwo
{
public abstract void ShowMessage();
public abstract void DisplayPlace();
}
class DerivedClass : AbstractClassOne, AbstractClassTwo // here under AbstractClassTwo it shows the error "cannot have multiple base classes:"
{
}
So a class can only derive from one abstract class?
If can derive from more than one abstract class, then what happens if both classes define the same method, as is the case above (abstract class one and two both have a method showmessage(), so which one will be in the derived class)?
Multiple inheritance is not allowed by C# but it is allowed by C++.
To answer your question regarding the ShowMessage() method that is a known problem in c++ with multiple inheritance called "The Diamond Problem". see: http://en.wikipedia.org/wiki/Multiple_inheritance
So basically you will have to excitability state to which method you are refereeing when calling it e.g. ParentA::ShowMessage()
if you want to have a type that is polymorphic to 2 other types than you should create two separate interfaces and implement them. and if you want to reuse the same methods than you will have to use compositions.
Interfaces example:
public interface ISomeInterface
{
public void ShowMessage();
public void DisplayName();
}
public class ClassOne : ISomeInterface
{
public void ShowMessage()
{
//implementation
}
public void DisplayName()
{
//implementation
}
}
public class ClassTwo : ISomeInterface
{
public void ShowMessage()
{
//implementation
}
public void DisplayPlace()
{
//implementation
}
}
Interface with reusable Show Message Method using composition:
public class ClassTwo : ISomeInterface
{
private ISomeInterface _MyPrivateReusableComponent = new ClassOne();
public void ShowMessage()
{
_MyPrivateReusableComponent.ShowMessage()
}
public void DisplayPlace()
{
_MyPrivateReusableComponent.DisplayName()
//implementation
}
}
In C# it's not allowed to inherit from more than one class. To do what you want here, you need to use interfaces.
abstract class AbstractClassOne
{
public abstract void ShowMessage();
public abstract void DisplayName();
}
Interface IClassTwo
{
void ShowMessage();
void DisplayPlace();
}
class DerivedClass : AbstractClassOne, IClassTwo
{
}
You can't inherit from more than one class (abstract or otherwise), but in your case the abstract classes are pretty much interfaces, so you can turn them into interfaces and inherit from them (you can inherit from any number of interfaces).
No, abstract class whether having all abstract methods or only some, makes no difference as far as inheritance in concerned. you can inherit only one class (in C#) and as many interfaces as you want.

Sealing an interface after implementing it

I am working on a small project and I came across that problem.
The project output is a library containing an interface. I would like to implement that interface and seal the functions in it like this if possible:
public interface ITest
{
void SomeMethod();
}
class A : ITest
{
public sealed override SomeMethod()
{
}
}
The idea is to have the interface available to everyone and have some specialized class that implements it. The exception is that I want to make sure that if someone create a specialized class of type A, he/she won't be able to change the method's behavior.
The problem is you can't put the "override" keyword in there since the method isn't declared as "virtual" in the interface. And you can't declare it as "virtual" in the interface since it's not allowed. And you can't remove the "override" keyword since it's needed by "sealed".
Any workaround or brainstorming idea would be welcome, but if someone can come up with a solution that includes an interface, I'd be really happy to learn it!
Thanks!
EDIT: Forget this question! Like Ani said, I forgot that by default method in C# are sealed. Seems like it's always good to go back to the basics once in a while...
I may have completely misunderstood the question, but if your intention is to seal the method in A, you can just do:
class A : ITest
{
public void SomeMethod() { ... }
}
Unlike Java, methods in C# are sealed by default. Subclasses of A won't be able to override the method since it hasn't been marked virtual.
On the other hand, if your intention is to mark the method 'almost sealed' in the interface, so that it forces upon an implementing class to immediately seal it, that isn't possible. It isn't (and shouldn't be) the business of the interface to dictate such details of implementation - an interface is meant to represent a specification.
Use an abstract base class with internal visibility. This base class is not visible outside of the library but allows you to seal the method and the class still implements the interface.
public interface ITest
{
void SomeMethod();
}
internal abstract class SuperA : ITest
{
public abstract void SomeMethod();
}
class A : SuperA
{
public sealed override void SomeMethod()
{
}
}
Your understanding of sealed keyword is incorrect. As a method modifier, sealed is used to prevent a virtual method(defined in the base class) to be override in the next generation of derived classes. For example:
class Base
{
public virtual void M() { }
}
class Derived : Base
{
public sealed override void M() { }
}
class A : Derived
{
public override void M() { } //compile error, M is sealed in Derived
}
Developers can always use new modifier to define a method with the same name in the derived class, that hides the one defined in the base class.
if someone create a specialized class
of type A, he/she won't be able to
change the method's behavior.
If "specialized class" means a class derived from A, the answer is: he can always hide the method in A, but he can't change the method's behavior.
Why not use an abstract class like below.
Haven't tested it but this should work?
public abstract class Test
{
public virtual void SomeMethod() {}
//OR
public abstract void SomeMethod();//MSDN says:
//an abstract method is implicitly virtual
}
class A : Test
{
public sealed override SomeMethod()
{
}
}
Methods in C# are sealed by default.. Here is a sample
class Program
{
static void Main(string[] args)
{
A obj = new A();
obj.SomeMethod();
b ss = new b();
ss.SomeMethod();
Console.ReadLine();
}
}
public interface ITest { void SomeMethod(); }
class A : ITest { public void SomeMethod() {
Console.WriteLine("SomeMethod Called from Class A object");
} }
class b : A
{
//public override void SomeMethod()
//{
// Console.WriteLine("Called from Class B Object");
//}
}

Explicitly implementing an interface with an abstract method

Here is my interface:
public interface MyInterface {
bool Foo();
}
Here is my abstract class:
public abstract class MyAbstractClass : MyInterface {
abstract bool MyInterface.Foo();
}
This is the compiler error:
"The modifier 'abstract' is not valid for this item.
How should I go on about explicitly implementing an abstract with an abstract method?
You can't, basically. Not directly, anyway. You can't override a method which is explicitly implementing an interface, and you have to override an abstract method. The closest you could come would be:
bool MyInterface.Foo() {
return FooImpl();
}
protected abstract bool FooImpl();
That still implements the interface explicitly and forces derived classes to actually provide the implementation. Are those the aspects you're trying to achieve?
You have to use an implicit implementation of the interface member instead of an explicit implementation:
public abstract class MyAbstractClass : MyInterface
{
public abstract bool Foo();
}
In fact there is another option than using an abstract helper method which still keeps the implementation private:
public abstract class MyAbstractClass : MyInterface
{
bool MyInterface.Foo() // must be overridden
{ throw NotImplementedException(); // never called
}
}
public class MyDerivedClass : MyAbstractClass, MyInterface
{
bool MyInterface.Foo() // overrides MyInterface.Foo
{ // Place your implementation here
}
}
This pattern will also work if the interface has many methods and only some of them are redefined in the derived class. And, of course, you can also use this to override private interface implementations in general.
The major disadvantage is that Foo cannot be declared abstract in MyAbstractClass, so the compiler cannot ensure that the method is actually overridden. (It's a pity that abstract classes may not have incomplete interface implementations in C#.)
The advantage is that you save one calli instruction that is likely to cause CPU pipeline stalls. However, the impact is quite small, since the method cannot be inlined anyway because of the interface call. So I would recommend it only for performance critical cases.
I'm not sure why you need to. Why not let the concrete implementation of the abstract class implement the member from the interface? It's the same thing really.
An abstract method has no implementation, so it can't be used to explicitly implement an interface method.
I am able to do this
public interface SampleInterface
{
void member1();
void member2();
void member3();
}
public abstract class Client2 : SampleInterface.SampleInterface
{
public void member1()
{
throw new NotImplementedException();
}
public abstract void member2();
public void member3()
{
throw new NotImplementedException();
}
}
public class Client3 : Client2
{
public Client3()
{
}
public override void member2()
{
throw new NotImplementedException();
}
}
In addition to Jon's explanation: this is a way to bypass the problem instead of solving it directly and will work only in certain circumstances, but maybe someone will benefit from this idea.
If you plan to pass all (or at lest most) interface method calls to the derived class, you can do it in the following way:
public interface MyInterface
{
bool Foo();
}
public abstract class MyAbstractClass
{
public abstract MyInterface AsMyInterface();
}
public class MyDerivedClass : MyInterface
{
public override MyInterface AsMyInterface()
{
return this;
}
public bool Foo()
{
return false;
}
}
...
MyAbstractClass c = new MyDerivedClass();
MyInterface i = c.AsMyInterface();
bool b = i.Foo();
Abstract all the interface methods that are implemented in a abstract class, even if you do not use them.
This particular case requires that you are implementing a hierarchy of 2 or more abstract classes, with a interface.
I was trying to implement a hierarchy in C# as well. I needed a Interface but I wanted a Abstract class, because most of the properties are the same for the interface. To do this I had to create a separate Abstract class, with the implementation, and then my Concrete classes, or in my case another abstract class, would inherit the Interface and the Abstract Class.
I do not think that this first one is a good example for many reasons, but I had to have it because the compiler would not allow FooBar to implement Foo and then have another abstract class to inherit FooBar. So I had a abstract class with a abstract method bar(), and the interface with the bar() method.
public interface Foo {
bool bar();
//other stuffs
}
public abstract class FooBar {
public abstract bool bar();
//Other stuffs
}
public abstract class FooBarAbstraction: FooBar, Foo {
//other stuffs
//Don't supply the interface and abstract here
}
public class FooBarConcrete: FooBarAbstraction {
public override bool bar() {
return true;
}
//other stuffs
}
This was my first attempt, then I got curious and started to think about it. I came across this solution. The better solution.
public interface Foo {
bool bar();
bool buzz();
//other stuffs
}
public abstract class FooBar : Foo{
public abstract bool bar();
public abstract bool buzz();
//Other stuffs
}
public abstract class FooBarAbstraction: FooBar {
//other stuffs
//Don't supply the interface and abstract here
// override everything else
public override bool buzz() {
return false;
}
}
public class FooBarConcrete: FooBarAbstraction {
public override bool bar() {
return true;
}
//other stuffs
}

Using interfaces on abstract classes in C#

I'm learning C# coming from C++ and have run into a wall.
I have an abstract class AbstractWidget, an interface IDoesCoolThings, and a class which derives from AbstractWidget called RealWidget:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget : IDoesCoolThings
{
void IDoesCoolThings.DoCool()
{
Console.Write("I did something cool.");
}
}
public class RealWidget : AbstractWidget
{
}
When I instantiate a RealWidget object and call DoCool() on it, the compiler gives me an error saying
'RealWidget' does not contain a
definition for 'DoCool'
I can cast RealWidget object to an IDoesCoolThings and then the call will work, but that seems unnecessary and I also lose polymorphism (AbstractWidget.DoCool() will always be called even if i define RealWidget.DoCool()).
I imagine the solution is simple, but I've tried a variety of things and for the life of me can't figure this one out.
You're running into the issue because you used explicit interface implementation (EII). When a member is explicitly implemented, it can't be accessed through a class instance -- only through an instance of the interface. In your example, that's why you can't call DoCool() unless you cast your instance to IDoesCoolThings.
The solution is to make DoCool() public and remove the explicit interface implementation:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool() // DoCool() is part of the abstract class implementation.
{
Console.Write("I did something cool.");
}
}
// ...
var rw = new RealWidget();
rw.DoCool(); // Works!
In general, you use EII in two cases:
You have a class that must implement two interfaces, each of which contains a member that has an identical name/signature to another member in the other interface.
You want to force clients not to depend on the implementation details of your class, but rather on the interface that's being implemented by your class. (This is considered a good practice by some.)
The way you implement the interface is explicit implement void IDoesCoolThings.DoCool(), if you choose implicit implement interface.
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
Then it will work.
Read this :
C# Interfaces. Implicit implementation versus Explicit implementation
Change your declaration to:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
You should do it this way:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget
{
public void DoCool()
{
Console.WriteLine("I did something cool.");
}
}
public class Widget : AbstractWidget, IDoesCoolThings
{
}
Usage:
var widget = new Widget();
widget.DoCool();

Categories

Resources