Java Interfaces vs. Abstract Classes

Jakob Jenkov
Last update: 2015-03-09

A question I get a lot is what the difference is between Java interfaces and abstract classes, and when to use each. Having answered this question by email multiple times, I decided to write this tutorial about Java interfaces vs abstract classes.

Java interfaces are used to decouple the interface of some component from the implementation. In other words, to make the classes using the interface independent of the classes implementing the interface. Thus, you can exchange the implementation of the interface, without having to change the class using the interface.

Abstract classes are typically used as base classes for extension by subclasses. Some programming languages use abstract classes to achieve polymorphism, and to separate interface from implementation, but in Java you use interfaces for that. Remember, a Java class can only have 1 superclass, but it can implement multiple interfaces. Thus, if a class already has a different superclass, it can implement an interface, but it cannot extend another abstract class. Therefore interfaces are a more flexible mechanism for exposing a common interface.

If you need to separate an interface from its implementation, use an interface. If you also need to provide a base class or default implementation of the interface, add an abstract class (or normal class) that implements the interface.

Here is an example showing a class referencing an interface, an abstract class implementing that interface, and a subclass extending the abstract class.

The blue class knows only the interface. The abstract class implements the interface, and the subclass inherits from the abstract class.
The blue class knows only the interface. The abstract class implements the interface, and the subclass inherits from the abstract class.

Below are the code examples from the text on Java Abstract Classes, but with an interface added which is implemented by the abstract base class. That way it resembles the diagram above.

First the interface:

public interface URLProcessor {

    public void process(URL url) throws IOException;
}

Second, the abstract base class:

public abstract class URLProcessorBase implements URLProcessor {

    public void process(URL url) throws IOException {
        URLConnection urlConnection = url.openConnection();
        InputStream input = urlConnection.getInputStream();

        try{
            processURLData(input);
        } finally {
            input.close();
        }
    }

    protected abstract void processURLData(InputStream input)
        throws IOException;

}

Third, the subclass of the abstract base class:

public class URLProcessorImpl extends URLProcessorBase {

    @Override
    protected void processURLData(InputStream input) throws IOException {
        int data = input.read();
        while(data != -1){
            System.out.println((char) data);
            data = input.read();
        }
    }
}

Fourth, how to use the interface URLProcessor as variable type, even though it is the subclass UrlProcessorImpl that is instantiated.

URLProcessor urlProcessor = new URLProcessorImpl();

urlProcessor.process(new URL("http://jenkov.com"));

Using both an interface and an abstract base class makes your code more flexible. It possible to implement simple URL processors simply by subclassing the abstract base class. If you need something more advanced, your URL processor can just implement the URLProcessor interface directly, and not inherit from URLProcessorBase.

Jakob Jenkov

Featured Videos

Java Generics

Java ForkJoinPool

P2P Networks Introduction



















Close TOC
All Tutorial Trails
All Trails
Table of contents (TOC) for this tutorial trail
Trail TOC
Table of contents (TOC) for this tutorial
Page TOC
Previous tutorial in this tutorial trail
Previous
Next tutorial in this tutorial trail
Next