I have a number Processor
classes that will do two very different things, but are called from common code (an "inversion of control" situation).
I'm wondering what design considerations I should be cognicent (or cognizant, for you USsers) of when deciding if they should all inherit from BaseProcessor
, or implement IProcessor
as an interface.
We can inherit lesser classes than Interface if we use Inheritance. We can inherit enormously more classes than Inheritance, if we use Interface. Methods can be defined inside the class in case of Inheritance. Methods cannot be defined inside the class in case of Interface (except by using static and default keywords).
To get the higher design flexibility, the design principle says that composition should be favored over inheritance. Inheritance should only be used when subclass 'is a' superclass. Don't use inheritance to get code reuse. If there is no 'is a' relationship, then use composition for code reuse.
One key advantage of interfaces in a single inheritance language is that interfaces can be implemented on classes that do not share a common root. Another point is that interfaces allow what is known as interface inheritance rather than implementation inheritance.
Inheritance creates dependency between child and parent, when a class inherit another class, we include all methods and attributes from parent class and expose to the child class, therefore we break the encapsulation, the child object can access all the methods in parent object and overwrite them.
Generally, the rule goes something like this:
To put this in somewhat more concrete terms, let's look at an example. The System.Drawing.Bitmap
class is-an image (and as such, it inherits from the Image
class), but it also can-do disposing, so it implements the IDisposable
interface. It also can-do serialization, so it implements from the ISerializable
interface.
But more practically, interfaces are often used to simulate multiple inheritance in C#. If your Processor
class needs to inherit from something like System.ComponentModel.Component
, then you have little choice but to implement an IProcessor
interface.
The fact is that both interfaces and abstract base class provide a contract specifying what a particular class can do. It's a common myth that interfaces are necessary to declare this contract, but that's not correct. The biggest advantage to my mind is that abstract base classes allow you provide default functionality for the subclasses. But if there is no default functionality that makes sense, there's nothing keeping you from marking the method itself as abstract
, requiring that derived classes implement it themselves, just like if they were to implement an interface.
For answers to questions like this, I often turn to the .NET Framework Design Guidelines, which have this to say about choosing between classes and interfaces:
In general, classes are the preferred construct for exposing abstractions.
The main drawback of interfaces is that they are much less flexible than classes when it comes to allowing for the evolution of APIs. Once you ship an interface, the set of its members is fixed forever. Any additions to the interface would break existing types implementing the interface.
A class offers much more flexibility. You can add members to classes that you have already shipped. As long as the method is not abstract (i.e., as long as you provide a default implementation of the method), any existing derived classes continue to function unchanged.
[ . . . ]
One of the most common arguments in favor of interfaces is that they allow separating contract from the implementation. However, the argument incorrectly assumes that you cannot separate contracts from implementation using classes. Abstract classes residing in a separate assembly from their concrete implementations are a great way to achieve such separation.
Their general recommendations are as follows:
Chris Anderson expresses particular agreement with this last tenet, arguing that:
Abstract types do version much better, and allow for future extensibility, but they also burn your one and only base type. Interfaces are appropriate when you are really defining a contract between two objects that is invariant over time. Abstract base types are better for defining a common base for a family of types.
Richard,
Why CHOOSE between them? I'd have an IProcessor interface as the published type (for use elsewhere in the system); and if it so happens that your various CURRENT implementations of IProcessor have common-behaviour, then an abstract BaseProcessor class would be a real good place to implement that common behaviour.
This way, if you require an IProcessor in future which does NOT have been for BaseProcessor's services, it doesn't HAVE to have it (and possibly hide it)... but those that do want it can have it... cutting down in duplicated code/concepts.
Just my humble OPINION.
Cheers. Keith.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With