Wednesday, November 5, 2014

My take on Abstract class vs Interface

Good evening, fellow readers!

Today I want to discuss a topic that is, apparently, an important one, when it comes to job interviews for junior developer positions. Specifically, the differences between an abstract class and an interface, and when one should be used over the other. Here goes.

An abstract class, in a nutshell, is a class, that has one or more abstract methods. A method is considered abstract if it has no implementations. For another class to inherit from an abstract class, it has to provide an implementation for those methods, or be considered abstract itself. For example, lets say you want to create a program, that draws shapes. You define a base abstract class:

public abstract class Shape {
    public abstract void draw(); // as this is an abstract method, the body is blank
    public int getColor() {
    //this is a concrete method, so it has a body
    }
}

And then you create some descendant classes:

public class Rectangle extends Shape {
    public void draw(){
    //this time, we will add code that does the actual drawing
    }
}

public class Circle extends Shape {
    public void draw(){
    //this time, we will add code that does the actual drawing
    }
}

As you can see, the draw() method is not implemented for the base class. This is because we do not know how to draw an undefined shape. A circle, or rectangle, on the other hand, are very specific shapes that have well-defined visual characteristics. The getColor() method can be used regardless of the actual shape, so we can provide an implementation in the base class.

The first way an abstract class is different from an interface is that an interface is not a class. It is basically just a collection of abstract methods. Any class that implements an interface must implement all of the method headings listed in the interface definition. There can be no method implementations inside the interface itself.

I find that a good way to look at the two is a "is-a" vs "has-a/can-do-this" type of relationship. For example, a cottage is a house, and it has an air-conditioning system. You could have an abstract class House, an AirConditioning interface, and a Cottage class that extends House and implements AirConditioning. So, one reason to use an interface over an abstract class is when there is no strong logical relationship between objects. A Car class might also need to implement an AirConditioning interface, but is is obviously not a House. Strictly speaking, relationships within the code, that make sense from a common point of view, are not required, but greatly improve code readibility, and, as a result, make it easier to maintain.

A second reason to use interfaces is the fact that Java does not support multiple inheritance, and interfaces provide a type of work-around (a class can extend only one class, but can implement any number of interfaces).

The last important difference is that an abstract class, unlike an interface, can have methods with actual implementation details, so shared methods can be placed right in the base class. This is especially important when the application design is constantly developing - if you add new method headings to an interface, then all of the classes that already implement that interface will have to be changed to implement the new methods, which can be quite a pain. With abstract classes, it is likely that you can just add the method to the abstract class.

Anyway, this covers the most important differences. The concept was a bit baffling for me for a while, so I hope this article helps people get a better understanding.

No comments:

Post a Comment