When I was first time working with an object oriented language (Java) on a project, suddenly a question came to my mind. What is the difference between abstract class and interface? The question was not about syntax because I knew that difference. The point was “How can I choose when to use an Abstract class and when to use an Interface?”
A few days ago me and my colleague had a similar discussion. That is why I decided to write some of my opinions about this topic.
It is not an either/or proposition. Although, many of those situations are depend on your solution, usually you cannot use abstract class over interface or vice versa.
When to Prefer an Abstract Class
First of all, let me consider when we should use an abstract class instead of a class. If we would never create an instance of base class, abstract class seems to be an appropriate choice. For example, let’s assume that we create an instance of animal objects like Dog, Cat, Elephant and so on. And there is a base class named Animal which is inherited by them. In this hierarchical structure we cannot instantiate the base class Animal since animal is not a concrete thing.
Second, you should use an abstract class when different objects have a common structure. In other words, in our example Dog “IS-A”(n) Animal, Cat “IS-A”(n) Animal. We can use “IS-A” terminology to define what is in common among related classes.
One more thing for abstract classes; If you want some default behaviour, you should prefer abstract classes. Because, interfaces do not have such property.
When to Prefer an Interface
An interface allows somebody to start from scratch implementation. Also, they allow you to implement different behaviours with same method signatures. Interfaces are useful when you do not want a massive hierarchical type framework.
For instance, consider the class Eagle. It is a descendant class of Animal. What is the difference between an eagle and other three animals? The eagle “CAN-DO” fly, which refers to its functional ability. We can implement IFlyable interface for Eagle. Now, assume that we have a tottally different class Plane. Plane is not an animal but it also can fly. So, Plane can inherit IFlyable interface too.
One more interesting point; Elephants are the only mammals that cannot jump. Thus, if we have an IJumpable interface Elephant class should not implement it (logically). But the other animals can. Now, lets take a look at the class diagram again.
IS-A vs. CAN-DO
You can see that some of the classes have more than one functionality (Eagle), i.e. “CAN-DO” property. Even some of them have completely different structure with same method signature (Eagle and Plane). But each object has only one “IS-A” definiton. Plane, for example, only IS-A vehicle not animal, or not both. Every class has only one parent.