Difference between abstract class and interface in Java

If you’re somewhat new to Java, you might have wondered what’s the difference between an abstract class and an interface. They sure pretty much seem like the same thing, right?

The interface in Java

Interfaces are commonly used when you want to decouple the the interface from the implementation.
Said in other words, an interface makes the classes using the interface independent of the classes implementing the interface.
Well, that even made my head spin, and I wrote it. Let’s illustrate it with an example.

Let’s assume you have an application consisting of three classes:

  • A class Driver, which is a person driving a either a car or a motorcycle.
  • A class representing a Motorcycle.
  • A class representing a Car.

If we implement this application without using an interface, our classes would probably look like this:

As you can see, we provide a Car into our Driver’s constructor.
What is the problem with this?

The problem with the code example above is that it is tightly coupled. Our Driver has to be constructed with a Car.
What would happen if the Driver got a motorcycle instead?

If the driver got a motorcycle instead of a car, we would have update our entire Driver class. The private variable vehicle would have to be changed from Car to Motorcycle and we would have to rewrite the constructor (providing a Motorcycle instead of a Car).

To further complicate things, we would also have to change the startDriving() and stopDriving() methods, so they call accelerateMc() and decelerateMc() instead of the methods in the Car class.

Now, how can we simplify this code, and remove the tightly coupled dependency between Driver and Car? Here comes to interface!

The first thing you might notice is the addition of a new class – the Driveable interface. What this interface actually tells us is that all classes implementing the Driveable interface, must contain the two methods accelerate() and decelerate().

This is perfect, since both the Car and the Motorcycle needs to be able to accelerate and decelerate. As you can see in the Car and Motorcycle class, it says implements Driveable.
The implementation of the Driveable interface forces these two classes to also implement all the methods defined in the interface!

Now, the real beauty of this can be seen in the Driver class. The Driver class no longer needs to know whether it uses a Car or a Motorcycle. It just relies on getting a Driveable object in the constructor.
Said in other words, the Driver class is unaware of what type of Driveable it is containing. And this is perfectly fine.

If you look at the startDriving() and stopDriving() methods in the Driver class, it now calls the Driveable.accelerate() and Driveable.decelerate(). You can’t go wrong doing this, since both the Car and the Motorcycle class has to implement these methods!

Our application is now fairly well designed, but it can still be improved. Let’s introduce the abstract class!

The abstract class in Java

A class that is declared using “abstract” keyword is known as abstract class. It can have abstract methods(methods without body) as well as concrete methods (regular methods with body).
A normal class(non-abstract class) cannot have abstract methods.
Abstract classes are typically used as base classes for extension by subclasses, thus inheriting methods and variable (unless defined as private in the abstract class).

Before going further, one thing needs to be made clear:

In our example, you could completely skip the interface, and use the abstract class to completely separate the concrete classes Car and Driver from the implementation.
However, in Java this is considered bad practice, and is what you would use an interface for, not an abstract class.

Okay, before creating the abstract class, let’s look at what Car and Motorcycle has in common:

  • They both implement the Driveable interface
  • They both contain a String object for “make” and “model”
  • They are both provided with make and model through the constructor.

With this knowledge, we can now implement our abstract class, the VehicleBase class.

As you can see, the VehicleBase class implements the Driveable interface. But, since the class is declared abstract, it does not need to implement the methods defined in the interface. That’s left for the subclasses!

We have now put all the common feature of the Car and the Motorcycle class in the VehicleBase class. Let’s update the Car and Motorcycle.

The first thing we notice is that there isn’t any private member variables anymore. These are now moved to the abstract super class, and given the visibility protected. This means that all subclasses of VehicleBase has access to those variables.

In the constructor, we make a call to super. This simply means that we want to invoke the superclass’ constructor, which assigns the make and model to the protected class variables.
Further, both the Car and Motorcycle class overrides the methods accelerate() and decelerate(), since their superclass VehicleBase implements this interface.

As for the Driver class, it remains unchanged. It still has a private member variable vehicle, which is a Driveable object.
Suppose we change the Driver class to contain a VehicleBase instead of a Driveable object. Would it still work?

Yes, it would still work! But would you want to do it this way? No!

Let’s illustrate why it’s generally a bad idea to use an abstract class instead of an interface to separate components from their implementation.
Our example will be that we have a new kind of driver, a WheelieDriver. This driver just has to do wheelies, so a Car would be completely unacceptable.

Interface vs abstract class

First, we need an object which can do a wheelie in the real world. We already have that, our Motorcycle class.
So, we want our Motorcycle class to be able to perform a wheelie. Where can we implement this logic?
We can’t implement this in the abstract super class VehicleBase, since Car also extends this class, and a Car can’t do a wheelie.

What about adding another abstract class, VehicleWheelieBase, which extends VehicleBase? And then make Motorcycle extend VehicleWheelieBase? And then provide our WheelieDriver with a VehicleWheelieBase through the constructor?
Sure, it is possible, but as the application grows, it would probably end up being a huge mess,  with a huge class hierarchy.
If we were to do that, we would also have to update a lot of our existing code, altering the whole class hierarchy.

Let’s try it using an interface instead, which we’ll call WheelieDriveable.

The WheelieDriveable extends Driveable, which means that on top of doWheelie(), it can also accelerate() and decelerate().

Now, let’s make the Motorcycle able to do a wheelie!

Do you see the beauty of this? We didn’t change our class hierarchy at all, apart from adding a new interface, and our Motorcycle can now do a wheelie.

Summary abstract class vs interface

Abstract classInterface
1 An abstract class can extend only one class or one abstract class at a time An interface can extend any number of interfaces at a time
2 An abstract class can extend another concrete (regular) class or abstract class An interface can only extend another interface
3 An abstract class can have both abstract and concrete methods An interface can have only abstract methods
4 In abstract class keyword “abstract” is mandatory to declare a method as an abstract In an interface keyword “abstract” is optional to declare a method as an abstract
5 An abstract class can have protected and public abstract methods An interface can have only have public abstract methods
6 An abstract class can have static, final or static final variable with any access specifier interface can only have public static final (constant) variable
Quick tip: If you wish to expand your Java skill-set and become an advanced Java developer, I highly recommend you to get yourself a copy of the best-selling Effective Java, by Joshua Bloch!

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *