When devising the architecture of your classes, a few concerns will pop up: You can leverage your implementations by using abstract base classes and
interfaces. Often these two raise a lot of confusion since they are similar, however, they actually have different implementations. Let’s find out when to use each. For this, we will see examples using different programming languages [Kotlin, TypeScript, Java], but the theory applies to all of them. A class can be declared abstract when you want common methods or
properties to be extended by other classes [or other abstract classes]. When an abstract class defines an abstract method, this method must be overridden by the extending subclass — unless the abstract class is extended by another abstract class, in which case you’ll get a cascading inheritance. These abstract methods, defined in the abstract class, are created having only their signature. They shouldn’t
have a body at this point, that will be defined in the overridden method.One defines an object’s characteristics, the other establishes a contract of what this object can do
Photo by Aleks Marinkovic on UnsplashWhat is an abstract class?
Likewise, you can define concrete [non-abstract] methods that will be inherited by the extending class.
Consider this:
- Professor X is a Professor, and he also, by extension, is a Person
- All Professors will greet you in a specific way: “Hi, I’m Professor…”
- All Persons will say goodbye the same way: “See you later!”.
- Every Person has an allegiance, and they can show their allegiance in the same way: “Long live…!”.
How would you do that with Object-Oriented Programming? First, let’s try Kotlin:
Example of an abstract base class in KotlinThe output of the previous script will be:
Starting up...
Hello, you can call me Doctor Doom.
Long live Sorcerers Supreme!
Hello, you can call me Professor X.
Long live X-Men!
The end.
In this case, what we did was create an abstract class Person, this class has two concrete methods [showLoyalty and sayGoodbye]. These two will be inherited to whatever extends this abstract.
We also have an abstract variable [allegiance]. This variable must be overridden by both classes that extend Person. These classes [Professor, Doctor] do this in their constructor. The name of the Person is also defined in the constructor.
Now, we see that each class overrides the abstract method intro defined in the abstract class. If they didn’t it would throw an error similar to this:
Class ‘Professor’ is not abstract and does not implement abstract base class member public abstract fun intro[]: Unit defined in Person
What is an interface?
An interface, on the other hand, is traditionally called a “contract”, and this contract will be enforced to whatever classes implement them.
In essence, an interface will show the users of the implementing class what this class is capable of doing. Contrariwise, an abstract defines a relation of equality: a Doctor is a Person.
Notice, also, that interfaces do not define the body of the method to be implemented.
Another thing you might notice is that, traditionally, interfaces are named with an “-able” suffix at the end. This is not mandatory but will help to identify their purpose. Other programmers tend to add “i-” as a prefix, such as that an interface Clone will end up being called IClonable — personally, I think this is overkill, but, to each its own!
Now, observe the following Java code:
Example of an interface in Java.The previous program will print out something like this into the terminal:
Abilities check...
Nightcrawler teletransported to X-Mansion.
Storm started to fly.
Suddenly we see 4 clones of Multiple Man.
End of exercise.
Here, the instantiated class is Student, which implements the interface Mutant. Mutant defines 3 methods: teleport, fly, and selfDuplicate. This means that these 3 methods must be implemented in the Student class. Otherwise, you’ll see an error like this:
Main.java:7: error: Student is not abstract and does not override abstract method selfDuplicate[int] in Mutant
Putting it all together
One nifty feature of Object-Oriented Programming is the ability to mix interfaces with abstract classes to have your class exactly as you wanted.
In the following TypeScript code, notice the definition of the class as class Male extends Person implements Mutantable
. Now, this is quite powerful since you can define this Male to be a Person and has the
capabilities of a Mutantable.
The previous code when run will produce the following output:
An X-Men Short Story
A new X-Men is about to be born...
Wolverine is born.
Checking Wolverine's abilities:
Regeneration: true
Fly: false
Wolverine met Kayla.
Kayla is now Wolverine's girlfriend.
The end.
Again, the main takeaway of this article is:
An interface will define what this class is capable of doing: a Doctor can operate[]
An abstract defines a relation of equality: a Doctor is a Person.