C# and Java are both wonderful languages that have matured and evolved over the last 14 years. This is great for us developers because a mature language provides us with a plethora of language features that are at our disposal.
However, with great power comes great responsibility. Some of these features can be misused, or sometimes it is hard to understand why you would choose to use one feature over another. Over the years, a feature that I have seen many developers struggle with is when to choose to use an interface or to choose to use an abstract class. Both have their advantages and disadvantages and the correct time and place to use each. But how do we decide???
Both allow for the use of polymorphic types (a type whose operations can also be applied to values of some other type, or types) and reuse of common functionality between types. The most obvious difference right away is that interfaces provide no implementation for their functionality whereas abstract classes allow you to implement some “base” or “default” behavior and then have the ability to “override” this default behavior with the classes derived types if necessary.
This is all well and good and provides for great reuse of code and adheres to the DRY (Don’t Repeat Yourself) principle of software development. Abstract classes are great to use when you have an “is a” relationship.
For example: A golden retriever “is a” type of dog. So is a poodle. They both can bark, as all dogs can. However, you might want to state that the poodle bark is significantly different than the “default” dog bark. Therefore, it could make sense for you to implement something as follows:
As you can see, this would be a great way to keep your code DRY and allow for the base class implementation be called when any of the types can just rely on the default Bark instead of a special case implementation. The classes like GoldenRetriever, Boxer, Lab could all could inherit the “default” (bass class) Bark at no charge just because they implement the Dog abstract class.
But I’m sure you already knew that.
You are here because you want to understand why you might want to choose an interface over an abstract class or vice versa. Well, one reason you may want to choose an interface over an abstract class is when you don’t have or want to prevent a default implementation. This is usually because the types that are implementing the interface are not related in an “is a” relationship. Actually, they don’t have to be related at all except for the fact that each type “is able” or has “the ability” to do something or have something.
Now, what the heck does that mean? Well, for example: A human is not a duck…and a duck is not a human. Pretty obvious. However, both a duck and a human have “the ability” to swim (given that the human passed his swimming lessons in 1st-grade :) ). Also, since a duck is not a human or vice versa, this is not an “is a” relationship, but instead, an “is able” relationship and we can use an interface to illustrate that:
Using interfaces like the code above will allow you to pass an object into a method that “is able” to do something. The code doesn’t care how it does it…All it knows is that it can call the Swim method on that object and that object will know which behavior take at run-time based on its type.
Once again, this helps your code stay DRY so that you would not have to write multiple methods that are calling the object to preform the same core function (ShowHowHumanSwims(human), ShowHowDuckSwims(duck), etc.)
Using an interface here allows the calling methods to not have to worry about what type is which or how the behavior is implemented. It just knows that given the interface, each object will have to have implemented the Swim method so it is safe to call it in its own code and allow the behavior of the Swim method be handled within its own class.
So my main rule of thumb is use an abstract class when you want to implement “default” functionality for a class hierarchy or/and the classes or types you are working with share an “is a” relationship (ex. poodle “is a” type of dog).
On the other hand, use an interface when you do not have an “is a” relationship but have types that share “the ability” to do something or have something (ex. Duck “is not” a human. However, duck and human share “the ability” to swim).
Another difference to note between abstract classes and interfaces is that a class can implement one to many interfaces but a class can only inherit from ONEabstract class (or any class for that matter). Yes, you can nest classes and have an inheritance hierarchy (which many programs do and should have) but you cannot inherit two classes in one derived class definition (this rule applies to C#. In some other languages you are able to do this, usually only because of the lack of interfaces in these languages).
Also, remember when using interfaces to adhere to the Interface Segregation Principle (ISP). ISP states that no client should be forced to depend on methods it does not use. For this reason, interfaces should be focused on specific tasks and are usually very small (ex. IDisposable, IComparable ).
Another tip is if you are developing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.
Hope this clears things up for some people!
Also, if you can think of any better examples or want to point something out, please do so in the comments below!
If you liked this post, please share it with others! That is the biggest compliment I could receive.
Original post: http://jasonroell.com/