Interface & Base Abstract Class c# - c#

Is it good practice to define an interface, implement the interface in a base abstract class, give it default behavior and then inherit from the base class?
Or it that overkill?

Whether to use an interface or an abstract class are two entirely different questions. It might happen that the answer to both is yes but one has nothing to do with the other.
Unless you're absolutely certain that you're going to need multiple classes that inherit from a base class and share certain methods, I wouldn't plan up front to use inheritance. When we start off envisioning some perfect textbook class hierarchy it often gets complicated and doesn't work out. It often makes more sense when you're refactoring or if you find yourself writing a similar class and don't want to duplicate code.
Writing an interface and then implementing it is a good practice when you're creating something that another class is going to depend on (which is very often.) For example, if you know that your class is going to depend on another class that "does something" then you can momentarily pause working on the first class to write the IDoesSomething interface, and finish the first class that depends on IDoesSomething. You haven't figured out what the implementation is yet, but it doesn't matter because the class you're already writing just depends on the interface. (Inversion of Control - good practice.) Then you can write a class that implements IDoesSomething.
Just to expound on that with an example. Suppose I'm writing a class that provides a Menu object which contains a nested list of MenuItem objects:
public class MenuProvider
{
public Menu GetMenu(string menuId)
{
//code that gets the menu
return menu;
}
}
Then I realize that I'm going to need to filter out certain menu items before returning it. That might be based on configuration settings, the particular user, or anything else.
I might write this interface:
public interface IMenuFilter
{
void FilterMenu(Menu menu);
}
and then modify my original class like this:
public class MenuProvider
{
private readonly IMenuFilter _menuFilter;
public MenuProvider(IMenuFilter menuFilter)
{
_menuFilter = menuFilter;
}
public Menu GetMenu(string menuId)
{
//code that gets the menu
//filter the menu
_menuFilter.FilterMenu(menu);
return menu;
}
}
I don't know what the implementation of IMenuFilter is going to be. In practice it might end up being a composite of a bunch of separate classes that each perform one type of filtering. But the point is that I don't need to stop what I'm doing on MenuProvider to figure that out. I can write this class and even test it with a mocked IMenuFilter, and then move on to write the specifics of that filter.

Do you have common functionality that you want to share amongst implementations of this interface? If so, then create an abstract base class. Otherwise, don't worry about it now. You can always add one later. But programming to interfaces is almost always a good idea.

Generally, you will use either an interface or inheritance. I don't normally don't use both with the same class.
Use inheritance when you want to inherit functionality from the base class.
Use an interface when you want disparate classes to implement some same core functionality, but not necessarily share code.

Related

How do I implement an interface if I don't need all of its functions?

I have a simple interface defined
public interface IBla
{
public void DoThing();
public void DoAnotherThing();
public void Thing();
}
I have a bunch of classes which implement this interface. Lots of them however only need two of the three functions which that interface implements, so currently I implement the remaining ones as well and just leave them empty like so:
public void DoThing(){}
Is there some more elegant way of doing this?
I do NOT want to have multiple interfaces defined for this.
Is there perhaps something like a "partialInterface" where I don't have to implement all of the functions from that interface into a class which implements that interface?
Thanks
When implementing an interface, the type that implements the interface must provide an implementation for everything that interface details.
There is no support for partial interfaces or anything similar to what you want, other than breaking up the interface.
You're basically asking "How can I implement the calculator interface without requiring me to provide the + operator" and in short, you can't. It would no longer be a calculator according to that interface.
The closest thing you get is that you can create a base class that provides default implementations for the whole interface or parts of it, and inherit from this base type, so that inherited classes become easier to implement with less code, but they will provide the entire interface.
I know you said you don't want separate interfaces, but for the benefit of others in future who want the right answer to this question here it is:
What you describe is the point at which you separate your interfaces out, and use interface inheritance.
public interface IBasic
{
void DoThing();
}
public interface IAdvanced : IBasic
{
void DoAnotherThing();
void Thing();
}
Implementations which only need DoThing only implement IBasic. Implementations which need all functionality implement IAdvanced which includes the method from IBasic plus the additional functionality.
If you have classes which implement not all methods, then you probably need to separate this interface into smaller interfaces.
Many specific interfaces are better than one universal.
Creating the classes which implement your interface, and throw NotImplementedException or simply do nothing looks like SOLID rules violation.
Well, it is highly discouraged to only partially implement an interface, there is a way to sort of do it.
Most answers talk about breaking up your interface into multiple interfaces, which makes sense. But, if this is not possible simply implement the members that you do not want to use in an explicit manner, and if they get called you should throw a NotSupportedException.
If you want to see an example of this in use, look no further than Microsoft's own code: http://referencesource.microsoft.com/#mscorlib/system/collections/objectmodel/readonlycollection.cs
void ICollection<T>.Add(T value)
{
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
Given that these things are being processed in a game loop, presumably implementations of IBla are things like the player character, enemies, obstacles, missiles and the like and DoThing etc and Move, Fire and so forth.
If so, then your approach is perfectly valid. An immobile object should have a Move method (so the game loop can call it), and since it can't move, an empty method is a valid implementation.
If you control both interfaces then separate the interfaces into multiple interfaces. As suggested, one interface can inherit from the other, or you could just have some classes implement both interfaces.
In this case interface inheritance is probably the better choice because you won't have to modify the classes that already implement the larger interface.
What if the larger interface is one you don't control, so splitting it into multiple interfaces isn't an option? It's not a good idea to implement the interface and leave some methods without implementations. If a class implements an interface then it should really implement the interface.
A solution is to define the smaller interface that you actually want and create a class that adapts the larger interface to your smaller one.
Suppose you have this interface
public interface IDoesFourThings
{
void DoThingOne();
void DoThingTwo();
void DoThingThree();
void DoThingFour();
}
And you want a class that only implements two of those things? You shouldn't implement IDoesFourThings if the class really only does two things.
So first, create your own interface:
public interface IDoesTwoThings
{
void DoThingA();
void DoThingB();
}
Then create a class that adapts an implementation of IDoesFourThings to your interface.
public class DoesTwoThingsUsingClassThatDoesFourThings : IDoesTwoThings
{
private readonly IDoesFourThings _doesFourThings;
public DoesTwoThingsUsingClassThatDoesFourThings(IDoesFourThings doesFourThings)
{
_doesFourThings = doesFourThings;
}
public void DoThingA()
{
_doesFourThings.DoThingTwo();
}
public void DoThingB()
{
_doesFourThings.DoThingThree();
}
}
Just for the sake of example I avoided naming the methods in IDoesTwoThings to match the ones in IDoesFourThings. Unless they're really exactly the same thing then the new interface doesn't need to match the old one. It is its own interface. That the class works by using an inner implementation of IDoesFourThings is hidden.
This relates to the Interface Segregation Principle, the I in SOLID. One way of thinking about it is this: An interface describes what a class does, but from the perspective of the client class it should describe what the client needs. In this case the client needs two things, not four.
This approach can be very helpful because it enables us to work on one class at a time and defer the implementation of other details. If we're writing a class and we realize that it's going to require a dependency that does two things, we can just write the interface for those two things and make our class depend on it. (Now that class is more testable because it depends on an interface which we can mock.) Then, whatever that new interface is that we just created, we can also create an implementation for that.
It's a great way to manage the complexity of writing code and avoid getting stuck because now we can just work on our one class with its single responsibility, not worrying too much about how the next class and the next one will work. (We likely have an idea how they will work, but maybe we don't. Either way it doesn't slow us down.)

Different uses of Interfaces in C#

I read a lot about C# and had my first practical exercises, but I am still a beginner and kind of lost at a certain point of my try understanding an existing, but not finished, MVC-concepted program.
I understand what interfaces are for and how I must implement an interface to a class or another interface to gain acces to its containing members, functions etc, but in the existing code I found another use of interfaces (in the declaration of a class):
private IViewControl m_viewControl = null;
private IModelControl m_modelControl = null;
This code doesn't come up in the class, which implemented those two interfaces, but in the class which doesn't implement those two interfaces at all!
So my questions are:
How is this usage of interfaces called? It is clearly not the regular implementation of an interface.
What kind of possibilities do I get through this way of using an interface?
Thanks a lot!
Bent
Please excuse my english, I'm not a native speaker.
Hey,
thank you all so much for your answers, can't even say which is the best since all answers seem to be helpful! I think I'm starting to get what this is about.
Thanks again!
The class which contains these lines
private IViewControl m_viewControl = null;
private IModelControl m_modelControl = null;
Has 2 references to other classes which implement these Interfaces. So to answer your first question, this is not the implementation of an interface, it is the usage of an interface.
To answer your second question: That is exactly why we use interfaces. The class which uses these interfaces does not care about their implementation. In your development process you can write a dummy implementation for one or the other, because you don't need it right now, but you can still run and test the rest of the application.
An other example: Let's image you want to write an application which uses some Database. Put all your database logic behind an interface. In version 1 of your app you might use an SQL Database. Do your classes, which write to the database, know that it is an SQL database? No, and they don't need to. So now you move on and decide you want to use a different database system. You just change the implementation behind the interface and your done.
Hope this helps.
These are two variables (actually member variables, which are known as fields, as they are members of an enclosing type).
They can be used to store any item that implements the interface, so you could put anything that implements IViewControl into m_viewControl and anything that implements IModelControl into m_modelControl.
It does mean, that the object you can assign to your variable has to have the interface implemented.
So it has to be the type of the interface.
What you see there is called composition. It means that your class has two fields that are instances of those types, not that it is implementing their interfaces.
Let's use cars for an analogy. "Car" is a pretty generic concept, so let's make it the interface. The Toyota someone own is an instance of some class (e.g.: Corolla), which in turn implements the Car interface. The wheels, on the other hand, are fields of the car. The tires in your Corolla may belong to the Pirelli class, which implements the Tire interface. But your car is not a tire - it has tires.
An interface is a way to make a type without any implementation at all, but which cannot be instantiated. You can then have other types implementing that interface, giving it logic - so you have many variations of that interface, each doing something in a different way. The point is that you are making sure that all the implementors of an interface have a set of known method signatures and properties - you may not know how they are implemented, but you can be sure they are there.
If you look at some of the namespaces in C# that have a lot of classes implementing the same interface, you may get a better idea of how they behave. For example, a lot of classes in System.Collections implement the (surprise) ICollection interface. That makes sure that all collections have, for example, a Count property, and a CopyTo method with a known signature.
This type of usage is great to restrict the usage of a particular object, or to write common code that can work on any number of classes. Let's say we have a class called Car that implements an interface called IDriveable:
public class Car : IDriveable
Now, in some other class, we can instantiate a Car object easily, like so:
Car myCar = new Car();
But what if the Car class has several public methods that we don't want to be accessed in this other section? Or we want to write a function that can work on any class that implements the IDriveable interface? We could instead create an instantiation of the IDriveable interface itself, and then assign a Car to it, like so:
IDriveable myDriveable = new Car();
Then, if the following code works on the IDriveable interface, ANY class that implements IDriveable would work fine on it, such as this example:
private void TurnLeft(IDriveable vehicle)
P.S. Your English usage is great!
The important thing about interfaces is that you aren't interested in what they are but what they can do. Consequently in this case you are only interested in the IViewControl elements of whatever object is assigned to that local variable, so it could be of any class that implements IViewControl and very probably that class can do lots of other things as well, but for these purposes the fact that it is an IViewControl is all that we care about.
An example might be that we have a class that is interested in things that can fly, it doesn't care about anything else, so we create an interface called IFlyingThing with an IFlyingThing.Fly() method. Then we can have a Bird, Plane, Butterfly and all kinds of other types that implement IFlyingThing and we can pass it to our class and it will just see IFlyingThing and call IFlyingThing.Fly() which might be Bird.Fly(), or Plane.Fly() on the actual object it has been passed. It doesn't care what the object is, only that it can fly.
Bird might also implement IFeatheredAnimal, plane might implement IHasJetEngines too but our class is only interested in the IFlyingThing interface so it doesn't want or need to know about these.
This helps us to avoid tying our code together too tightly and makes techniques such as Inversion of Control and Mock Objects possible.
As you progress through learning C# you will use interfaces a lot.
Suppose you have a class, that you don't develop. You just consume it. You know it can generate some file and return it to you as a filestream. You don't know how it is generated, and you need not. You just know it returns you a filestream, which you then use for your own purpose. In order to implement it, you make a contract with a developer of the class that the class should provide you a method, which should return you a file stream and the name of the method should be ReturnStream, for example. This contract is called an Interface. By the time the developer of the class can change it's logic of file generation. But it would still have the same name ReturnStream and it would still return you a file stream. So you don't have to change anything in your code.
As for your code, you have two objects of IViewControl and IModelControl. You don't develop the model and view. You just consume the logic of other developers, who write the classes with the interface implementation. And you can use them in your code in a way you want. But many developers can create different classes, which implement IViewControl and IModelControl interfaces. And you can use them by simply changing the class instance, which implements the interface.
Doesn't sound like you've grasped properly how interfaces can be used. Let me enlighten you with a simple example:
class Driver{
// A driver has two cars - they are cars, since they are
// of types (classes Bmw and Audi) that implement the interface ICar:
ICar firstCar = MethodThatReturnsInstanceOfBmw();
ICar secondtCar = MethodThatReturnsInstanceOfAudi();
public void DriveAllCars(){
// The interface ICar has a method "Start()", which both
// cars must therefor implement. The Driver class can call
// these methods, because it knows about them from the interface.
firstCar.Start();
secondCar.Start();
}
}
The class Driver still does not need to implement ICar - just know about it (have a reference to it), so it knows what it can do with "things" of that type. It can then tell a car to Start(), without giving a rodents rear part about how the engine actually works.
Compare it to the real world: You don't need to be a car to drive, nor do you need to be a mechanic - you just need to know the basics of driving, and those are common to most cars, though engines and other things may differ greatly.
That abstraction and agreement on common functionality, is the purpose of interfaces.
Interface is basically used to implement similar feature among different classes.
Interface is also used to create object of class only when it is required via a dependency injection.
eg:
Interface IMyClass{}
Class MyClass1:IMyClass
{
}
and
IMyClass obj;
thus you can register obj with the class that implements IMyClass in one class(Bootstrapper) and inject obj into all the class through constructor or method that required it with out need of initializing it.
thus Interface Prevents unnessecary creation of object thus prevent memory leak and as I mentioned above it helps in implementing same feature among different classes in different way.

Object oriented design: when to make an abstract class

Right now, I am learning OOP, mainly in c#. I am interested in what are the main reasons to make a class that can't be instantiated. What would be the correct example of when to make an abstract class?
I found myself using the abstract class in inheritance way too enthusiastically. Are there some rules when class is abstract in system and when class should not be abstract?
For instance, I made doctor and patient classes which are similar in some way so I derived them both from abstract class Person (since both have name and surname). Was that wrong?
Sorry if the question is stupid, I am very new at this.
There are a couple of things no one has pointed out so far, so I would just like to point them out.
You can only inherit from one base class (which could be abstract) but you can implement many interfaces. So in this sense inheriting an abstract class is a closer relationship than implementing an interface.
So if you later on realize that you have a need for a class which implements two different abstract classes you are in deep shit :)
To answer your question "when to make an abstract class" I'd say never, avoid it if possible, it will never pay off in the long run, if the main class is not suitable as a ordinary class, it probably isn't really needed as abstract either, use an interface. If you ever get in the situation where you are duplicating code it might be suitable with an abstract class, but always have a look at interfaces and behavioral patterns first (ex the strategy pattern solves a lot of issues people wrongly use inheritance to solve, always prefer composition over inheritance). Use abstract classes as a last hand solution, not as a design.
To get a better understanding of OOP in general, I'd recommend you to have a look at Design Patterns: Elements of Reusable Object-Oriented Software (a book) which gives a good overview of OO-design and reusability of OO-components. OO-design is about so much more than inheritance :)
For Example: you have a scenario where you need to pull data from different sources, like "Excel File,XML,any Database etc" and save in one common destination. It may be any database. So in this situation you can use abstract classes like this.
abstract class AbstractImporter
{
public abstract List<SoldProduct> FetchData();
public bool UploadData(List<SoldProduct> productsSold)
{
// here you can do code to save data in common destination
}
}
public class ExcelImporter : AbstractImporter
{
public override List<SoldProduct> FetchData()
{
// here do code to get data from excel
}
}
public class XMLImporter : AbstractImporter
{
public override List<SoldProduct> FetchData()
{
// here do code to get data from XML
}
}
public class AccessDataImporter : AbstractImporter
{
public override List<SoldProduct> FetchData()
{
// here do code to get data from Access database
}
}
and calling can be like this
static class Program
{
static void Main()
{
List<SoldProduct> lstProducts;
ExcelImporter excelImp = new ExcelImporter();
lstProducts = excelImp.FetchData();
excelImp.UploadData(lstProducts);
XMLImporter xmlImp = new XMLImporter ();
lstProducts = xmlImp.FetchData();
xmlImp.UploadData(lstProducts);
AccessDataImporterxmlImp accImp = new AccessDataImporter();
lstProducts = accImp .FetchData();
accImp.UploadData(lstProducts);
}
}
So, in Above example, implementation of data import functionality is separated in extended (derived) class but data upload functionality is common for all.
This is probably a non-academic definition, but an abstract class should represent an entity that is so "abstract" that make no sense to instantiate it.
It is often used to create "templates" that must be extended by concrete classes. So an abstract class can implement common features, for example implementing some methods of an interface, an delegate to concrete classes implementation of specific behaviors.
In essence what you have done is fine if you never want to instantiate a Person class, however as I'm guessing you may want to instantiate a Person class at some point in the future then it should not be abstract.
Although there is an argument that you code to fix current issues, not to cater for issues which may never arise, so if you need to instantiate Person class do not mark it as abstract.
Abstract classes are incomplete and must be implemented in a derived class... Generally speaking I tend to prefer abstract base classes over interfaces.
Look into the difference between abstract classes and interfaces...
"The difference between an abstract class and an interface is that an abstract class can have a default implementation of methods, so if you don't override them in a derived class, the abstract base class implementation is used. Interfaces cannot have any implementation." Taken from this SO post
As already stated, noone will force you to use abstract classes, it is just a methodology to abstract certain functionality which is common among a number of classes.
Your case is a good example where to use abstract classes, because you have common properties among two different types. But of cause it restricts you to use Person as a type by itself. If you want to have this restriction is basically up to you.
In general, I would not use abstract classes for Model like classes as you have unless you want to prevent Person from being instantiated.
Usually I use abstract classes if I also have defined an interface and I need to code different implementations for this interface but also want to have a BaseClass which already covers some common functionality for all implementations.
Deriving both 'Doctor' and 'Patient' from an abstract class 'Person' is fine, but you should probably make Person just a regular class. It depends on the context in which 'Person' is being used, though.
For example, you might have an abstract class named 'GameObject'. Every object in the game (e.g. Pistol, OneUp) extends 'GameObject'. But you can't have a 'GameObject' by itself, as 'GameObject' describes what a class should have, but doesn't go into detail as to what they are.
For example, GameObject might say something like: "All GameObjects must look like something'. A Pistol might extend on what GameObject said, and it says "All Pistols must look like a long barrel with a grip on one end and a trigger."
The key is whether instantiation of that class ever makes sense. If it will never be appropriate to instantiate that class, then it should be abstract.
A classic example is a Shape base class, with Square, Circle and Triangle child classes. A Shape should never be instantiated because by definition, you don't know what shape you want it to be. Therefore, it makes sense to make Shape an abstract class.
Incidentally, another issue which hasn't yet been mentioned is that it is possible to add members to an abstract class, have existing implementations automatically support them, and allow consumers to use implementations which know about the new members and implementations which don't, interchangeably. While there are some plausible mechanisms by which a future .NET runtime could allow interfaces to work that way as well, at present they do not.
For example, if IEnumerable had been an abstract class (there are of course good many reasons why it isn't), something like a Count method could have been added when its usefulness became apparent; its default implementation of Count could behave much like the IEnumerable<T>.Count extension method, but implementations which knew about the new method could implement it more efficiently (although IEnumerable<T>.Count will try to take advantage of implementations of ICollection<T>.Count or ICollection.Count, it first has to determine whether they exist; by contrast, any override would know that it has code to handle Count directly).
It would have been possible to add an ICountableEnumerable<T> interface which inherited from IEnumerable<T> but included Count, and existing code would continue to work just fine with IEnumerable<T> as it always had, but any time an ICountableEnumerable<T> was passed through existing code, the recipient would have to recast it to ICountableEnumerable<T> to use the Count method. Far less convenient than having a directly-dispatched Count method which could simply act directly on IEnumerable<T> [the Count extension method isn't horrible, but it's far less efficient than would be a directly-dispatched virtual method].
If there were a means by which an interface could include static methods, and if the class loader, upon finding that a class Boz which claimed to implement IFoo, was missing method string IFoo.Bar(int), would automatically add to that class:
stringIFoo.Bar(int p1) { return IFoo.classHelper_Bar(Boz this, int p1); }
[assuming the interface contains that static method], then it would be possible to have interfaces add members without breaking existing implementations, provided that they also included static methods that could be called by default implementations. Unfortunately, I know of no plans to add any such functionality.

Why can't my public class extend an internal class?

I really don't get it.
If the base class is abstract and only intended to be used to provide common functionality to public subclasses defined in the assembly, why shouldn't it be declared internal?
I don't want the abstract class to be visible to code outside the assembly. I don't want external code to know about it.
UPDATE: This question was the subject of my blog on November 13th of 2012. See it for some more thoughts on this issue. Thanks for the great question!
You're right; it doesn't have to be that way. Other OO languages allow "private inheritance", whereby the fact that D inherits from B can only be taken advantage of by code that has the ability to see B.
This was a design decision of the original C# designers. Unfortunately I am away from my desk right now - I'm taking a couple of days off for the long weekend - so I don't have the language design notes from 1999 in front of me. If I think of it when I get back I'll browse them and see if there is a justification for this decision.
My personal opinion is that inheritance should be used to represent "is a kind of" relationships; that is, inheritance should represent the semantics of the domain being modelled in the language. I try to avoid situations where inheritance is used as a code sharing mechanism. As others have mentioned, it's probably best to prefer composition to inheritance if what you want to represent is "this class shares implementation mechanisms with other classes".
By inheriting from a class, you expose the functionality of the base class through your child.
Since the child class has higher visibility than its parent, you would be exposing members that would otherwise be protected.
You can't violate the protection level of the parent class by implementing a child with higher visibility.
If the base class is really meant to be used by public child classes, then you need to make the parent public as well.
The other option is to keep your "parent" internal, make it non-abstract, and use it to compose your child classes, and use an Interface to force classes to implement the functionality:
public interface ISomething
{
void HelloWorld();
}
internal class OldParent : ISomething
{
public void HelloWorld(){ Console.WriteLine("Hello World!"); }
}
public class OldChild : ISomething
{
OldParent _oldParent = new OldParent();
public void HelloWorld() { _oldParent.HelloWorld(); }
}
I think the closest thing you can do is prevent other assemblies creating the abstract class by making its constructor internal, to quote from MSDN:
An internal constructor prevents the abstract class from being used as the base class of types that are not in the same assembly as the abstract class.
You can then try adding an EditorBrowsableAttribute to the class to try and hide it from IntelliSense (though, I've had mixed results using it to be honest) or put the base class in a nested namespace, such as MyLibrary.Internals to seperate it from the rest of your classes.
I think you're mixing concerns here, and C# is to blame, actually (and Java before it).
Inheritance should serve as a categorization mechanism, whereas it's often used for code reuse.
For code reuse it's always been known that composition beats inheritance. The problem with C# is that it gives us such an easy way to inherit:
class MyClass : MyReusedClass { }
But in order to compose, we need to do it by ourselves:
class MyClass {
MyReusedClass _reused;
// need to expose all the methods from MyReusedClass and delegate to _reused
}
What's missing is a construct like a trait (pdf), which will bring composition to the same usability level as inheritance.
There's research about traits in C# (pdf), and it would look something like this:
class MyClass {
uses { MyTrait; }
}
Although I'd like to see another model (that of Perl 6 roles).
UPDATE:
As a side note, the Oxygene language has a feature that lets you delegate all members of an interface to a member property that implements that interface:
type
MyClass = class(IReusable)
private
property Reused : IReusable := new MyReusedClass(); readonly;
implements public IReusable;
end;
Here, all interface members of IReusable will be exposed through MyClass and they'll all delegate to the Reused property. There are some problems with this approach, though.
ANOTHER UPDATE:
I've begun implementing this automatic composition concept in C#: take a look at NRoles.
I think this would violate the Liskov Substitution Principle.
In cases like this, I have used internal classes and prefer composition over inheritance. Is there anything about your design that prohibits containing all such functionality in your internal class, and then have your public classes contain an instance of this internal class?

implementing polymorphism in c#, how best to do it?

first question here, so hopefully you'll all go gently on me!
I've been reading an awful lot over the past few days about polymorphism, and trying to apply it to what I do in c#, and it seems there are a few different ways to implement it. I hope I've gotten a handle on this, but I'd be delighted even if I haven't for clarification.
From what I can see, I've got 3 options:
I can just inherit from a base
class and use the keyword
'virtual' on any methods that I
want my derived classes to
override.
I could implement an abstract class with virtual methods
and do it that way,
I could use an interface?
From what I can see, if I don't require any implementation logic in the base, then an interface gives me the most flexibility (as I'm then not limiting myself with regards multiple inheritance etc.), but if I require the base to be able to do something on top of whatever the derived classes are doing, then going with either 1 or 2 would be the better solution?
Thanks for any input on this guys - I have read so much this weekend, both on this site and elsewhere, and I think I understand the approaches now, yet I just want to clarify in a language specific way if I'm on the right track. Hopefully also I've tagged this correctly.
Cheers,
Terry
An interface offers the most abstraction; you aren't tied to any specific implementation (useful if the implementation must, for other reasons, have a different base class).
For true polymorphism, virtual is a must; polymorphism is most commonly associated with type subclassing...
You can of course mix the two:
public interface IFoo {
void Bar();
}
class Foo : IFoo {
public virtual void Bar() {...}
}
class Foo2 : Foo {
public override ...
}
abstract is a separate matter; the choice of abstract is really: can it be sensibly defined by the base-class? If there is there no default implementation, it must be abstract.
A common base-class can be useful when there is a lot of implementation details that are common, and it would be pointless to duplicate purely by interface; but interestingly - if the implementation will never vary per implementation, extension methods provide a useful way of exposing this on an interface (so that each implementation doesn't have to do it):
public interface IFoo {
void Bar();
}
public static class FooExtensions {
// just a silly example...
public static bool TryBar(this IFoo foo) {
try {
foo.Bar();
return true;
} catch {
return false;
}
}
}
All three of the above are valid, and useful in their own right.
There is no technique which is "best". Only programming practice and experience will help you to choose the right technique at the right time.
So, pick a method that seems appropriate now, and implement away.
Watch what works, what fails, learn your lessons, and try again.
Interfaces are usually favored, for several reasons :
Polymorphisme is about contracts, inheritance is about reuse
Inheritance chains are difficult to get right (especially with single inheritance, see for instance the design bugs in the Windows Forms controls where features like scrollability, rich text, etc. are hardcoded in the inheritance chain
Inheritance causes maintenance problems
That said, if you want to leverage common functionnality, you can use interfaces for polymorphism (have your methods accept interfaces) but use abstract base classes to share some behavior.
public interface IFoo
{
void Bar();
enter code here
}
will be your interface
public abstract class BaseFoo : IFoo
{
void Bar
{
// Default implementation
}
}
will be your default implementation
public class SomeFoo : BaseFoo
{
}
is a class where you reuse your implementation.
Still, you'll be using interfaces to have polymorphism:
public class Bar
{
int DoSometingWithFoo(IFoo foo)
{
foo.Bar();
}
}
notice that we're using the interface in the method.
The first thing you should ask is "why do I need to use polymorphism?", because polymorphism is not and end by itself, but a mean to reach an end. Once you have your problem well defined, it should be more clear which approach to use.
Anyway, those three aproaches you commented are not exclusive, you still can mix them if you need to reuse logic between just some classes but not others, or need some distinct interfaces...
use abstract classes to enforce a class structure
use interfaces for describing behaviors
It really depends on how you want to structure your code and what you want to do with it.
Having a base class of type Interface is good from the point of view of testing as you can use mock objects to replace it.
Abstract classes are really if you wish to implement code in some functions and not others, as if an abstract class has nothing other than abstract functions it is effectively an Interface.
Remember that an abstract class cannot be instantiated and so for working code you must have a class derived from it.
In practice all are valid.
I tend to use an abstract class if I have a lot of classes which derive from it but on a shallow level (say only 1 class down).
If I am expecting a deep level of inheritence then I use a class with virtual functions.
Eitherway it's best to keep classes simple, along with their inheritence as the more complex they become the more likelyhood of introducing bugs.

Categories