Home

 › 

Articles

 › 

Vs.

 › 

Abstract Class vs. Interface: Full Comparison With Examples

C++ vs. JavaScript

Abstract Class vs. Interface: Full Comparison With Examples

One of the main principles of Object-oriented programming (OOP) is the use of abstract classes and interfaces. Programmers often use these techniques to enforce encapsulation and share properties and behaviors among derived classes without having to repeat code.

What’s the Difference Between an Abstract Class and an Interface?

At a high level, an abstract class is one that we cannot instantiate on its own, and an interface is a contract of rules that a class must abide by. Usually, we implement abstract classes with the “abstract” keyword and interfaces with the “interface” keyword. While abstract classes often contain abstract methods, i.e. those without implementation that must be overridden, they can also contain non-abstract methods. You can think of abstract methods as similar to pure virtual functions in C++. The main objective of abstract classes is to provide properties and methods to be used by derived classes. In this way, they serve as a kind of template or blueprint.

On the other hand, interfaces give a set of guidelines to a class, and can provide functionality, but they don’t contain any implementation. This can be thought of as similar to an abstract class, but interfaces can’t have non-abstract methods or member variables like abstract classes can. Abstract classes do define a contract in a way, but they can also provide non-abstract methods. Many programming languages, such as Java, allow you to implement interfaces directly using the “interface” keyword. However, we can also implement interfaces via an abstract class, so that we can reuse the abstract method. It should be noted that classes can only extend from one abstract class, but can extend from several interfaces at once.

You can refer to the table below for a summary of the key differences between abstract classes and interfaces.

Abstract Class vs. Interface: Summary

Abstract classInterface
Used to provide properties and methods to derived classes to be overridden.Used to provide contracts and functionality to classes.
Can be used to implement an interface.Can’t be used to implement an abstract class.
Usually declared with the abstract keyword.Usually declared using the interface keyword.
Can contain either abstract or non-abstract methods.Can only contain abstract methods.
Only one class can be extended from an abstract class.Classes can extend from multiple interfaces.
Can have protected, public or private members.Their members are always public by default.

Why Use Abstract Classes and Interfaces?

There are many reasons to use both abstract classes and interfaces, but common ones are to enforce encapsulation, inheritance, polymorphism, and loose coupling. Because they lack implementation, abstract class methods are protected from being directly modified by external code. The functionality of the abstract methods is controlled by the abstract class, with subclasses providing a specific implementation. In addition, abstract classes are used to achieve inheritance, as derived classes will inherit the properties from the abstract class.

As mentioned before, the main purpose of interfaces is to provide a set of guidelines to classes. This allows us to enable polymorphism, where we can treat objects as if they’re of the same class. Abstract classes also enable this, however, since they provide a base class that can be inherited by multiple classes. Interfaces also help to encourage loose coupling, since they give us a way for classes to interact based on guidelines rather than particular implementations. This keeps the dependency of the classes on each other to a minimum.

When Should Abstract Classes and Interfaces Be Used?

Ultimately, the decision to use either an abstract class or interface depends on the needs of your project and what you want to achieve. Abstract classes are more suited to providing an incomplete implementation or behavior to be inherited by multiple related classes. In addition to this, abstract classes are more useful when you plan on expanding the class further in the future, as new methods are easier to add than with interfaces. However, if you want to define a contract and provide behavior for classes that aren’t as related, an interface is more appropriate. When you need a class to implement several contracts, an interface is also preferable. In both cases, the goal is usually to make code more reusable, modular and flexible.

Advantages and Disadvantages of Abstract Class vs. Interface

Now we’ve covered the basics of what abstract classes and interfaces are, along with their differences, it’s time to move on to the advantages and drawbacks of each. We’ve summarized these in the following tables, starting with abstract classes.

Pros and Cons of Abstract Class

ProsCons
Useful for providing a partial implementation for reusing code.Some languages, i.e. Java and C++ only allow inherit from one abstract class.
Used to promote inheritance.Derived classes are tightly coupled to the abstract class, since they must inherit its behavior and properties.
Abstract methods provide flexibility while adhering to a contract.
New methods and properties can be added without detrimentally affecting derived classes.
Variety of access modifiers can be used to control access to the contents.

Next up, here are the pros and cons of using interfaces.

Pros and Cons of Interface

ProsCons
Can support multiple inheritance.Don’t provide implementation, which can lead to duplicate code being used if classes act similarly.
Encourages loose coupling since classes depend on contract rather than a particular implementation.Use of access modifiers is limited, as all members are public by default.
Helps to enable polymorphism by ensuring objects of different classes adhere to the same rules.Adding new methods often requires modifying all classes that implement the interface, which is more challenging than modifying an abstract class.

Implementation

It would be a good idea at this point to show how abstract classes and interfaces work in practice. To this end, we’ll demonstrate both concepts with a relatively simple example, in Java, C#, C++, and Python.

Abstract Class Example in Java

First, consider this code:

abstract class Shape {
    public abstract void draw();
}

class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle.");
    }
}

public class Abstractclass {
    public static void main(String[] args) {
        Circle circle = new Circle();
        circle.draw();
        
    }
}

We start by declaring the “Shape” abstract class, with the “draw()” abstract method. After, we extend the Shape class with the “Circle” derived class, inheriting the draw method and providing its own implementation. We use “@Override” to indicate that this method overrides the abstract method from the Shape class.

To finish, we declare the “Abstractclass” class, including the “main()” method. We create an instance of the Circle class and call the draw method, which prints the “Drawing a circle” message to the console. You can see the result in the image below.

Java abstract class
A simple example of an abstract class in Java.

Abstract Class Example in C++

Implementation in C++ is similar, but there are a few differences. To see this, take a look at the following code:

#include <iostream>

class Shape {
public:
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

int main() {
    Circle circle;
    circle.draw();
    
    return 0;
}

Overall, much of the code is the same. We declare the Shape and Circle classes and print the same message. However, we use a pure virtual function, which is somewhat analogous to an abstract method, and is declared using the “virtual” keyword and “= 0”. We also use an explicit “override” keyword in C++. The output statements also differ in their syntax, but provide the same result.

A point to note is that C++ doesn’t support the implementation of interfaces. The best we can do is to emulate an interface by using abstract classes and pure virtual functions, as has been done here.

Abstract class example in C++
An example of using abstract class in C++.

Abstract Class Example in C#

Now, let’s look at how we can implement this using C# instead. As an example, we have this code block:

using System;

abstract class Shape
{
    public abstract void Draw();
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a circle.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Circle circle = new Circle();
        circle.Draw();

Console.ReadLine();
    }
}

Despite the name, this code is more similar to the Java example than the C++ example. Both use the abstract keyword and similar methods. However, we use “Console.WriteLine” and “Console.ReadLine” here to write and print the specified string, and also the “Program” class as a starting point for the program.

Abstract class example using C sharp.
Implementing an abstract class in C#.

Abstract Class Example in Python

The situation in Python is a little different since it doesn’t have built-in functionality for abstract methods. However, we can get around this by using an abstract method decorator. These give us a way to modify a function without changing the source code. For example, we have this code block:

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def draw(self):
        pass

class Circle(Shape):
    def draw(self):
        print("Drawing a circle.")

circle = Circle()
circle.draw()

Firstly, we have to import the ABC module, which is the “Abstract Base Classes” module. We then define the Shape class as normal, as well as the draw method, which we declare as an abstract method using the decorator. We define the Circle class afterwards, which inherits the draw method and provides its own print method as before. Finally, we create an instance of the Circle class and print the same message.

Similarly to C++, Python doesn’t have support for creating interfaces, but this is a similar approach.

Abstract class using abstract methods in Python.
Python’s approach to implementing abstract classes.

Interface Example in Java

Next, let’s move on to an example of using an interface. Consider this code:

interface Drawable {
    void draw();
}

class Circle implements Drawable {
    @Override
    public void draw() {
        System.out.println("Drawing a circle.");
    }
}

class Rectangle implements Drawable {
    @Override
    public void draw() {
        System.out.println("Drawing a rectangle.");
    }
}

public class InterfaceExample {
    public static void main(String[] args) {
        Drawable circle = new Circle();
        Drawable rectangle = new Rectangle();
        
        circle.draw();
        rectangle.draw();
    }
}

We define the “Drawable” interface, and declare the “draw()” method. After this, we define the “Circle” class, which implements the interface and overrides the draw method. Similarly, we define the “Rectangle” class, which also inherits the draw method. Lastly, we define the public class “InterfaceExample”, which contains the “main()” method used to begin the program. We assign instances of the “circle” and “rectangle” variables, and call the draw method on these to produce the messages in the output.

Example of implementing an interface in Java.
A simple example of implementing an interface in Java.

Interface Example in C#

While we can’t implement interfaces in C++ or Python, we can in C#. To show this, here is some example code.

interface IDrawable
{
     void Draw();
}

class Circle : IDrawable
{
       public void Draw()
       {
             Console.WriteLine("Drawing a circle.");
       }
}

class Rectangle : IDrawable
{
       public void Draw()
       {
             Console.WriteLine("Drawing a rectangle.");
       }
}

class InterfaceExample
{
       static void Main(string[] args)
       {
            IDrawable circle = new Circle();
            IDrawable rectangle = new Rectangle();

            circle.Draw();
            rectangle.Draw();
       }
}

We use the “interface” keyword here, as we did in Java. Instead of using the “implements” keyword like Java, however, C# uses a colon instead. Both methods use an override, but C# uses a keyword rather than an annotation.

Example of an interface in C#.
A basic example of implementing an interface using C#.

Wrapping Up

In summary, you can make your code more flexible and reusable by understanding the differences between abstract classes and interfaces. While both introduce a level of abstraction, interfaces focus on defining contracts, whereas abstract classes can include abstract and concrete methods. A class can also inherit from multiple interfaces, but from only one abstract class. While both encourage polymorphism, interfaces provide looser coupling between classes. If you intend to expand and add new methods, it’s easier to do this with an abstract class. If you want to inherit from multiple classes and these classes aren’t too related, an interface is preferable. Java and C# support interfaces directly, but other languages like Python and C++ can emulate them. Ultimately, your decision will come down to the specific needs of your project and any design considerations.

Frequently Asked Questions

What's the biggest difference between an abstract class and an interface?

The major difference between the two is that an abstract class provides abstract and concrete methods, which have implementation, whereas an interface can only provide a contract with no implementation. Classes can inherit from only one abstract class, but from multiple interfaces. Abstract classes can also use access modifiers, but interface members are always public.

Which should I use, an abstract class or an interface?

If you want to provide implementation for a variety of related classes, an abstract class is best. If you want to define a set of guidelines for classes that may not be related, interfaces are preferable. Similarly, interfaces are the better choice if you intend to take advantage of multiple inheritance.

Can I use an abstract class together with an interface?

Yes, in fact, abstract classes are often used to implement interfaces. This helps to achieve a balance of enforcing a contract and providing implementation.

Which programming languages support abstract classes and interfaces?

Many languages support abstract classes, including C++, C#, Python and Java. Both C# and Java support interfaces but C++ and Python do not. You can emulate an interface with these languages, however, by using abstract methods.

Can you change an abstract class to an interface?

Yes, you can actually change an abstract class to an interface and also an interface into an abstract class. But this will require you to modify your code and updating the class hierarchy, so be sure you need to do this before proceeding.

Can I create an instance of an interface or an abstract class?

No, neither can be instantiated directly, since they primarily serve as templates.

To top