Trouble with Interfaces, Inheritance, and Polymorphism - c#

I have come to a point in my program where my polymorphism is broken. I realize that this is in my code, and I understand why; I'm just not sure how best to resolve it.
I have three model classes which have the same interface, but very significantly different implementations. I created an interface, and then three independent classes, which also derive from a ModelBase class:
public interface IMyModel
{ ... }
public class MyModelA : ModelBase, IMyModels
{ ... }
public class MyModelB : ModelBase, IMyModels
{ ... }
public class MyModelC : ModelBase, IMyModels
{ ... }
So far fine and dandy.
I have a ViewModel base class, which takes a model as a constructor:
public abstract class MyViewModelBase
{
public MyViewModelBase(ModelBase Model)
this.model = Model;
}
Now where I am caught; I want to have a concrete ViewModel class that can accept any of the three Model classes above:
public class MyViewModel : MyViewModelBase
{
MyViewModel(IMyModel Model) : base (Model) // <- Invalid Polymorphism!
{
// More here
}
}
This doesn't work, because it is possible for an implementation of IMyModel to not be based on ModelBase. The argument cannot be safely passed to the base constructor.
I can see one solution being to create an abstract base class derived from ModelBase for these models with exception-throwing content, and using that as the type in my ViewModel. I had started with a base class, but found that almost every part had some difference! However, that seems like a lot of work. Also, it won't ensure that derived classes implement everything (like an interface does). Finally, it seems to devalue the interface concept (indeed, I wouldn't need one anymore).
I don't see any way of marking the interface as saying that derived classes must have a specific base class. It would be nice if I could do this, but it's not allowed:
public interface IMyModel : MyModelBase
{ ... }
Is there a better way to do this?
Clarification:
I probably oversimplified the names here. I have other Models and ViewModels using the base classes, but not implementing the interface.
public class MyOtherModel : ModelBase // But not IMyModel!
{ ... }
public class MyOtherViewModel : MyViewModelBase
{
MyOtherViewModel(MyOtherModel Model) : base(Model) // This works
{ ... }
}

You could make your base class implement the interface, then inherit your implementation classes from the base class, marking the base class and methods as abstract (MustInherit/MustOverride in VB parlance). This would give you your polymorphism and guarantee the interface.

you could use generic constraints:
public class MyViewModel<T> : MyViewModelBase where T : IMyModel , ModelBase
{
MyViewModel(T model) : base (model) // T inherits ModelBase and implements IMyModel , so it is legal
{
// More here
}
}

Often (not always) when you find yourself building an Abstract Base Class it means you are trying to share both an interface and some common logic. Perhaps you can split these two things?
Move the common interface into IMyModels, and extract the common functionality into a separate class. Then include an instance of that helper class in each model. Essentially use composition to share functionality instead of inheritance.

Make ModelBase implement IMyModel. If ModelBase does not implement all methods of the interface, implement them as abstract methods.

To my understanding
Models are stupid Data containers
Interfaces describe behaviour and Functionality, not data.
So why bother putting interfaces on the models at all?
#Yochai : Good point, using Generics - saves code, but you must first declare base classes (only one per class, there's no mixed inheritance in C#), then any amount of interfaces, thus your code should be:
public class MyViewModel<T> : MyViewModelBase where T : ModelBase, IMyModel

Related

What is MultiLayer Inheritence in C#?

Is it like a class can inherit from both an Interface and a base class?
Probably you mean multilevel inheritance, but it's just a chain of classes inheriting, starting from some base class.
It's like this example class structure:
public class Vehicle { ... } // base class
public class CombustionVehicle : Vehicle { ... } // intermediary class
public class Truck : CombustionVehicle { ... } // derived class
The Truck instance is still a Vehicle, so it still can use it's properties and methods (of course if the access modifier allows it).
I think you are confused here by the term multi layer.
multiple inheritance is not supported in C#. A class cannot directly inherit from more than one base class.
C# supports multilevel inheritance, which means that a class can inherit from a class that itself inherits from another class. For example:

Why is an Array an abstract class in C#? [duplicate]

The C# spec, section 10.1.1.1, states:
An abstract class is permitted (but
not required) to contain abstract
members.
This allows me to create classes like this:
public abstract class A
{
public void Main()
{
// it's full of logic!
}
}
Or even better:
public abstract class A
{
public virtual void Main() { }
}
public abstract class B : A
{
public override sealed void Main()
{
// it's full of logic!
}
}
This is really a concrete class; it's only abstract in so far as one can't instantiate it. For example, if I wanted to execute the logic in B.Main() I would have to first get an instance of B, which is impossible.
If inheritors don't actually have to provide implementation, then why call it abstract?
Put another way, why does C# allow an abstract class with only concrete members?
I should mention that I am already familiar with the intended functionality of abstract types and members.
Perhaps a good example is a common base class that provides shared properties and perhaps other members for derived classes, but does not represent a concrete object. For example:
public abstract class Pet
{
public string Name{get;set;}
}
public class Dog : Pet
{
public void Bark(){ ... }
}
All pets have names, but a pet itself is an abstract concept. An instance of a pet must be a dog or some other kind of animal.
The difference here is that instead of providing a method that should be overridden by implementors, the base class declares that all pets are composed of at least a Name property.
The idea is to force the implementor to derive from the class as it is intended to provide only a basis for a presumably more specialized implementation. So the base class, while not having any abstract members may only contain core methods an properties that can be used as a basis for extension.
For example:
public abstract class FourLeggedAnimal
{
public void Walk()
{
// most 4 legged animals walk the same (silly example, but it works)
}
public void Chew()
{
}
}
public class Dog : FourLeggedAnimal
{
public void Bark()
{
}
}
public class Cat : FourLeggedAnimal
{
public void Purr()
{
}
}
I think a slightly more accurate representation of your question would be: Why does C# allow an abstract class with only concrete members?
The answer: There's no good reason not to. Perhaps someone out there has some organizational structure where they like to have a noninstantiatable class at the top, even if a class below it just inherits and adds nothing. There's no good reason not to support that.
You said it -- because you can't instantiate it; it is meant to be a template only.
It is not "really a concrete class" if you declare it as abstract. That is available to you as a design choice.
That design choice may have to do with creating entities that are (at risk of mixing the terminology) abstractions of real-world objects, and with readability. You may want to declare parameters of type Car, but don't want objects to be declarable as Car -- you want every object of type Car to be instantiated as a Truck, Sedan, Coupe, or Roadster. The fact that Car doesn't require inheritors to add implementation does not detract from its value as an abstract version of its inheritors that cannot itself be instantiated.
Abstract means providing an abstraction of behaviour. For example Vehicle is an abstract form. It doesn't have any real world instance, but we can say that Vehicle has accelerating behaviour. More specifically Ford Ikon is a vehicle, and Yamaha FZ is a vehicle. Both these have accelerating behaviour.
If you now make this in the class form. Vehicle is abstract class with Acceleration method. While you may/ may not provide any abstract method. But the business need is that Vehicle should not be instantiated. Hence you make it abstract. The other two classes - Ikon and FZ are concrete classes deriving from Vehicle class. These two will have their own properties and behaviours.
With regards to usage, using abstract on a class declaration but having no abstract members is the same as having the class public but using protected on its constructors. Both force the class to be derived in order for it to be instantiated.
However, as far as self-documenting code goes, by marking the class abstract it informs others that this class is never meant to be instantiated on its own, even if it has no virtual or abstract members. Whereas protecting the constructors makes no such assertion.
The compiler does not prevent implementation-logic, but in your case I would simply omit abstract ?! BTW some methods could be implemented with { throw Exception("must inherit"); } and the compiler could not distinguish fully implemented classes and functions including only throw.
Here's a potential reason:
Layer Supertype
It's not uncommon for all the objects
in a layer to have methods you don't
want to have duplicated throughout the
system. You can move all of this
behavior into a common Layer
Supertype.
-- Martin Fowler
There's no reason to prevent having only concrete methods in an abstract class - it's just less common. The Layer Supertype is a case where this might make sense.
I see abstract classes serving two main purposes:
An incomplete class that must be specialized to provide some concrete service. Here, abstract members would be optional. The class would provide some services that the child classes can use and could define abstract members that it uses to provide its service, like in the Template Method Pattern. This type of abstract class is meant to create an inheritance hierarchy.
A class that only provides static utility methods. In this case, abstract members don't make sense at all. C# supports this notion with static classes, they are implicitly abstract and sealed. This can also be achieved with a sealed class with a private constructor.

(Regular Class + interface) vs Abstract class

I recently encountered a question on abstract class.
Functionality of Abstract classes can be achieved by using combination of (Regular class with Protected Constructor + an interface).
What is the benefit of using Abstract Class over (Regular class with protected constructor + interface).
IMHO, Purpose of Abstract class to have common feature that needs to be available across the class hierarchy. It can pose restriction on sub-classes to implement certain features by Abstract methods. It can allow Sub-Classes to override the common behavior.
Abstract Class doesn't serve a purpose of as concrete object. So, It doesn't allow to instantiate the abstract class.
However,We can achieve same thing using Regular Class + interface.
Mark Regular Class constructor as protected, So object can't be created alone
provide default implementation of common features and mark them virtual in case if they need to be overridden by sub class.
Use interface to force sub-classes to implement certain features.
So, Is there any extra feature which Abstract class offer?
I could not think of any other. Interviewers was trying to know what other benefits Abstract class have over Regular Class with protected constructor + interface.
A lot of good reasons. Let's start with an unambiguous one:
public abstract class Smell
{
public abstract string GetAdjective();
public string GetDescription()
{
return "I smell " + GetAdjective();
}
}
public class NastySmell : Smell
{
public override string GetAdjective() { return "really nasty"; }
}
Pretty simple. The abstract class has a function, GetDescription - which relies on the presence of an abstract method GetAdjective.
How could you do this with ProtectedConstructor+Interface? You can't have Smell implement the interface (for lots of reasons, but a big one being that any derived classes would also inherit the implementation and wouldn't be required to implement anything new) - but that means that it's function can't refer to the method:
public interface SmellInterface
{
string GetAdjective();
}
public class Smell
{
protected Smell() { }
public string GetDescription()
{
// how do I call GetAdjective here? I have no reference to it!
}
}
But here's another, even more compelling reason:
public abstract class SomeFancyClass
{
protected string name;
protected string server;
protected abstract string implementer { get; }
public string Generate()
{
if (name == "something")
HandleGlobally(name);
else
HandleSpecifically(name);
}
public void HandleGlobally(string server)
{
// code
}
public abstract void HandleSpecifically(string server);
}
... if you make this class a combo ProtectedConstructorClass + Interface, you split up code into two separate spots - and suddenly, you have to look through two halves to get the full picture of what's going on!
public interface AbstractHalf
{
// data property of 'implementer'
// method of 'HandleSpecifically()
}
public class NonabstractHalf
{
// data fields of 'name' and 'server'
// methods of 'Generate()' and 'HandleGlobally'
}
... why would you want to do this? Your class is a distinct, logical entity. Why would you split it up into two separate parts: the non-abstract versus the abstract? It'd just make it harder to read and troubleshoot. And it'd get worse, the more code and abstract declarations were made in the class.
The main benefit of the abstract class is to force the developer to create a subclass that inherits from the abstract class in order to use base/shared functionality and fields.
You cannot directly new-up an abstract class. You can new-up a regular class + interface, and you are not forced to inherit or override anything in the base.
With an abstract class, you can reduce the number of files - i.e. no interfaces, but most folks would probably like to keep those for registration with an IoC container and dependency injection.
One thing that I can think of is that by using an abstract class you can force a specific implementation simply by not marking a method or property as virtual, while using an interface you can't prevent classes from implementing the interface but not derive from your base class.
Another benefit of using an abstract class is that you can simply add functionality to your abstract class without having to worry about having all your derived classes implementations - again, since you can't prevent a class from implementing an interface without deriving from your base class.
Also, an abstract class can have protected fields, methods, events etc', but an interface can't.
It all boils down to the fact that you can't force classes that implement your interface to derive from your "regular" base class.
First of all, there is many questions and answers about differences between Abstract Class and Interfaces like: this. There are a lot of remarkable answers. But most of them are about programming and syntax.
I want to look from Design Perspective:
I think that Abstract Class can not play the Role of Interface (+ Regular Class)
in Software Design.
Abstract Class:
The main goal of Abstract Class is Abstraction Principle. To overcome this complexity, Abstract classes are used to make Hierarchies in similar looking classes. All classes in the hierarchy are extending base classes functionalities and extending types of base classes.
Interface:
However, Interfaces are used for Interactions between classes. These classes can be similar or not. They can be from different hierarchies and different types.
Also, they are huge difference between inheriting from a class (even Abstract class) and implementing an interface. Interfaces are not TYPES. They are shared boundary across which two or more separate components of a computer system exchange information.

Base class implementing interface

What are the cons/risks of base class implementing an interface?
Is it better to always implement an interface on the sub-class?
When would you use one or the other?
public interface IFriendly
{
string GetFriendly();
}
public abstract class Person: IFriendly
{
public abstract string GetFriendly();
}
VS.
public interface IFriendly
{
string GetFriendly();
}
public abstract class Person
{
// some other stuff i would like subclasses to have
}
public abstract class Employee : Person, IFriendly
{
public string GetFriendly()
{
return "friendly";
}
}
Well, you need to think of it that way:
public interface IBreathing
{
void Breathe();
}
//because every human breathe
public abstract class Human : IBreathing
{
abstract void Breathe();
}
public interface IVillain
{
void FightHumanity();
}
public interface IHero
{
void SaveHumanity();
}
//not every human is a villain
public class HumanVillain : Human, IVillain
{
void Breathe() {}
void FightHumanity() {}
}
//but not every is a hero either
public class HumanHero : Human, IHero
{
void Breathe() {}
void SaveHumanity() {}
}
The point is that you base class should implement interface (or inherit but only expose its definition as abstract) only if every other class that derives from it should also implement that interface.
So, with basic example provided above, you'd make Human implement IBreathing only if every Human breaths (which is correct here).
But! You can't make Human implement both IVillain and IHero because that would make us unable to distinguish later on if it's one or another. Actually, such implementation would imply that every Human is both a villain and hero at once.
To wrap up answers to your question:
What are the cons/risks of base class implementing an interface?
None, if every class deriving from it should implement that interface too.
Is it better to always implement an interface on the sub-class?
If every class deriving from base one should also implement that interface, it's rather a must
When would you use one or the other?
If every class deriving from base one should implement such interface, make base class inherit it. If not, make concrete class implement such interface.
Starting with a base class ties you to the implementation of the base class. We always start off thinking the base class is exactly what we want. Then we need a new inherited class and it doesn't quite fit, so we find ourselves going back and modifying the base class to fit the needs of the inherited class. It happens all the time.
If you start with an interface then you have a little more flexibility. Instead of having to modify the base class you can just write a new class that implements the interface. You can have the benefit of class inheritance when it works, but you're not tied to it when it doesn't work.
I loved class inheritance when I first started with OOP. What's surprising is how infrequently it ends up being practical. That's where the principal of Composition Over Inheritance comes in. It's preferable to build functionality out of combinations of classes rather than having it nested inside inherited classes.
There's also the Open/Closed principle. If you can inherit, great, but you don't want to have to go back and change the base class (and risk breaking other stuff) because it's needed for a new inherited class to work right. Programming to an interface instead of a base class can protect you from having to modify existing base classes.

Circular generic types in inheritance - why does it work?

Consider the following:
public class EntityBase<TEntity>
{
public virtual void DoSomethingWhereINeedToKnowAboutTheEntityType()
{
}
}
public class PersonEntity : EntityBase<PersonEntity>
{
public override void DoSomethingWhereINeedToKnowAboutTheEntityType()
{
}
}
I added this into code and ran it and it worked ok, but I'm surprised that I can inherit a class who's definition is based on the inheriting class.
When I tried it I was expecting either it not to compile, or to fail once actually called.
You can do something similar with an interface:
public interface IEntityBase<TEntity>
{}
public class PersonEntity : IEntityBase<PersonEntity>
{}
I've actually switched my code from the former to the later, using the interface, but I'm still curious why this works.
It works because there's no reason why it wouldn't work. EntityBase<PersonEntity> doesn't inherit from PersonEntity, it merely references the type. There's no technical problem with a base class knowing about its own derived class. This also works (even though this specific example is a bad idea):
public class A
{
public B AsB()
{
return this as B;
}
}
public class B : A
{
}
I'm surprised that I can inherit a class who's definition is based on the inheriting class.
Careful - what you're inheriting is a class whose definition involves an arbitrary Type, is all. All of these are legal:
class O : EntityBase<object>
class S : EntityBase<String>
class Q : EntityBase<Q>
All you've said in the definition of EntityBase is that TEntity should be a type - well, PersonEntity is a type, isn't it? So why shouldn't it be eligible to be a TEntity? No reason why not - so it works.
You might be concerned about the order of definitions, but remember that within the unit of compilation, everything gets defined 'at once' - there's no sense in which PersonEntity needs to be compiled 'before' anything else (including itself!) can refer to it. Indeed, you're even allowed
class A : EntityBase<B>
class B : EntityBase<A>
for which no conceivable 'order of compilation' could work, if such a thing were needed.
A very simple example is the generic interface IComparable<T>. Usually, you implement it like this:
class MyClass : IComparable<MyClass> {/*...*/}
This implementation of the generic template is just saying that MyClass objects can compare to other MyClass objects. As you can see, there is no problem with the mental model. I can very well understand the concept of a class whose objects can compare between them without knowing anything else about the class.
The main point here is that template parameters are just used by the generic class or interface, but they need not be related by inheritance at all. IComparable<MyClass> does not inherit from MyClass. So there is no circularity.

Categories