Core Java

Interface vs Abstract Class Java Example

In this post, we feature an Interface vs Abstract Class Java Example. One of the most discussed topics in Java for newbies is the Interface and Abstract class. I will give insights into the Java Interfaces and abstract classes. I will also provide some examples and practical use cases.

You can also check the Java Abstract Class Example in the following video:

This image has an empty alt attribute; its file name is Java-Abstract-Class-Example-1024x576.jpg
Java Abstract Class Example – Video

1. Introduction

Abstraction, Encapsulation, and Inheritance are the basic ingredients of an Object-Oriented Language. Interface and Abstract Classes fall under inheritance.

1.1. Class

Class is the basic structure in the object-oriented language. They provide a blueprint of a real-world object. They contain object attributes and their concrete behaviors (called as methods). A concrete class can be instantiated to create any number of objects.

1.2 Abstract Class

Abstract classes are special form of a class where some of the behaviors (methods) don’t have a concrete definition. These behaviors are just a declaration (these type of methods are called abstract methods). Abstract classes can’t be instantiated. Any of the concrete class should inherit an abstract class and provide a definition of the abstract method. An abstract class can have attributes and access modifiers like a class.

1.3. Interface

Interfaces are another special Object-Oriented structure which contains only abstract methods. They are just like protocols and the implementing classes should provide definition to all the methods in the interfaces. Apart from methods they can have public static variables. Java 8 has enhanced interfaces with additional feature and we will see them later in the article.

2. Interface vs Abstract Class Java Example – Differences

The following table lists the abstract vs interface :

Interface Abstract class
Declared as public interface Interface Declared as public abstract class AbstractClass
Can contain only abstract methods Can contain both abstract and non abstract (concrete) methods
Only public final constants are allowed Variables/ attributes with all access modifiers (private, protected, public and default) are allowed. It can have both final and static attributes too.
All methods are public All the access modifiers are allowed
Support multiple inheritance Don’t support multiple inheritance
Interfaces should be implemented using keyword implements. eg: class ExampleClass implements ExampleInterface An abstract class can be extended by using the extends keyword. eg: class ExampleClass extends ExampleAbstractClass
An interface can extend one or more interfaces only An abstract class can extend another abstract class and can implement one or more interfaces
Interfaces cannot be instantiated or invoked Abstract classes cannot be instantiated, but can be invoked if they have main method
Static methods aren’t allowed in an interface Both static and non-static methods are allowed

Even though, abstract classes with only abstract methods and final constants can provide similar feature as interfaces, why Java created interfaces?

Java by default doesn’t support multiple inheritance. One class can extend behavior from only one another class or abstract class. This restriction is applied to avoid Diamond Problem.

Diamond problem” is the ambiguity problem that arises as a side effect of multiple inheritance. It generally happens in languages that allow multiple inheritance of the state (Ex: C++). Java solves it by not allowing multiple inheritance. Below diagram explains the classic diamond problem. Class A provides a definition for method m and Class B and Class C are derived from A. They both get method m’s implementation from A. Now a new Class D extends both B and C. This is where the confusion arises, which definition of method m will Class D get?

Interface vs Abstract Class Java - Classic diamond problem
Classic diamond problem

Java solves it by using interfaces. Since interfaces don’t provide method definitions, it is the responsibility of the implementing class to provide a definition. Hence, there is no confusion.

3. Examples

In this section, I will provide examples of interfaces and abstract classes.

3.1. Interface

MobilePhone interface defines the contract of any type of mobile phones in the example,

/**
 * @author Santosh Balgar Sachchidananda
 * MobileInterface defines the contract which all types of mobile phones
 * in the example have to adhere to
 */
public interface MobilePhone {
    void makeACall(Long number, Integer countryCode);
    boolean sendSMS(String message);
}

BasicMobilePhone class implements the MobilePhone interface. It has to provide definition for all the methods in MobilePhone interface. Otherwise, implementing class has to be declared as abstract.

/**
 * author Santosh Balgar Sachchidananda
 * BasicMobilePhone implements MobilePhone interface and provide definition for all the methods.
 * It also has additional method apart from the interface contract
 */
class BasicMobilePhone implements MobilePhone {
    /**
     * @param number
     * @param countryCode
     * Overridden from MobilePhone interface
     */
    @Override
    public void makeACall(Long number, Integer countryCode) {
        System.out.println(String.format("I can call to number %d-%d", countryCode, number));
    }

    /*
     * @param message
     * @return
     * Overriden from MobilePhone interface
     */
    @Override
    public boolean sendSMS(String message) {
        System.out.println("I can send SMS");
        return true;
    }

    /**
     * Own method
     */
    public void supportClassicGames() {
        System.out.println("I can support classic games");
    }
}

SmartPhone is the another class adhering to the MobilePhone contract.

/**
 * @author Santosh Balgar Sachchidananda
 * SmartPhone class implements MobilePhone interface. It has to provide definition for all the methods.
 * Also it has additional methods.
 */
class SmartPhone implements MobilePhone {
    /**
     * @param number
     * @param countryCode
     * Overridden from MobilePhone interface
     */
    @Override
    public void makeACall(Long number, Integer countryCode) {
        System.out.println(String.format("I can make audio and video call to %d-%d", countryCode, number));
    }

    /**
     * @param message
     * @return
     * Overridden from MobilePhone interface
     */
    @Override
    public boolean sendSMS(String message) {
        System.out.println("I can send SMS");
        return true;
    }

    /**
     * own method of SmartPhone class
     */
    public void canCapturePhoto() {
        System.out.println("I can take HD photo");
    }
}

InterfaceDemo is the driver class which can be invoked to run the example.

/**
 * author Santosh Balgar Sachchidananda
 * InterfaceDemo is the driver class for interfaces
 */
public class InterfaceDemo {
    public static void main(String[] args) {
        MobilePhone basicMobilePhone = new BasicMobilePhone();
        MobilePhone smartPhone = new SmartPhone();

        System.out.println("Basic Mobile Phone features");
        basicMobilePhone.makeACall(1234567890L, 91);
        basicMobilePhone.sendSMS("Hello world!!!");
        ((BasicMobilePhone) basicMobilePhone).supportClassicGames();
        System.out.println("-------------------------------------------------");
        System.out.println("Smart Phone features");
        smartPhone.makeACall(1234567890L, 91);
        smartPhone.sendSMS("Hello world!!!");
        ((SmartPhone) smartPhone).canCapturePhoto();
    }
}

Below is the output of InterfaceDemo,

Interface vs Abstract Class Java - InterfaceDemo output
InterfaceDemo output

When there is a need to inherit from multiple interfaces then use the syntax similar to public class ClassA implements Interface1, Interface2. ClassA should provide definition to the methods from both Interface1 and Interface2.

3.2. Abstract Class

AndroidPhone is an abstract class that adheres to the MobilePhone interface. AndroidPhone will have to exhibit certain behaviors and all other classes extending from it have to adhere to it.

import com.jcg.java7.interfaces.MobilePhone;
import com.jcg.java7.interfaces.MobilePhone;

/**
 * @author Santosh Balgar Sachchidananda
 * AndroidPhone is an abstract class. This defines the construct for any android phone in the example.
 * Basic phone contract is implemented from MobilePhone interface. However the definitions of those
 * methods have to be provided in the class extended from the AndroidPhone
 */

abstract class AndroidPhone implements MobilePhone {
    /**
     * Concrete method in the abstract class
     */
    public final void displayPhoneOSType() {
        System.out.println("I run on Android OS");
    }

    /**
     * An abstract method. Inheriting class should provide the definition
     */
    public abstract void capturePhoto();
}

BrandAPhone is of AndroidPhone type and provides a definition of abstract method.

import com.sun.deploy.util.StringUtils;
import com.sun.deploy.util.StringUtils;

/**
 * @author Santosh Balgar Sachchidananda
 * BrandAPhone is a Android type phone. It extends AndroidPhone bstract class
 */
class BrandAPhone extends AndroidPhone{
    @Override
    //Overridden from AndroidPhone abstract class
    public void capturePhoto() {
        System.out.println("BrandAPhone can capture photo");
    }

    @Override
    //Method contract from the MobilePhone interface
    public void makeACall(Long number, Integer countryCode) {
        System.out.println(String.format("BrandAPhone can make audio and video calls to 0%d-%d", countryCode, number));
    }

    @Override
    //Method contract from MobilePhone interface
    public boolean sendSMS(String message) {
        System.out.println(String.format("BrandAPhone can send text message - %s", message));
        return true;
    }
}

BrandAPhoneDemo is the driver class to run the abstract class demo.

/**
 * @author Santosh Balgar Sachchidananda
 * This is the driver program to demonstrate the abstract class
 */
public class BrandAPhoneDemo {
    public static void main(String[] args) {
        System.out.println("This class demonstrates the use of abstract class in Java");
        System.out.println("----------------------------------------------------------");
        AndroidPhone brandAPhone = new BrandAPhone();
        //Final method inherited from AndroidPhone abstract class
        brandAPhone.displayPhoneOSType();

        brandAPhone.makeACall(1234567890L, 91);

        brandAPhone.sendSMS("Hello, world!!!!");

        brandAPhone.capturePhoto();
        System.out.println("----------------------------------------------------------");
    }
}

The output from BrandAPhoneDemo is as below,

Interface vs Abstract Class Java - BrandAPhoneDemo output
BrandAPhoneDemo output

4. Java 8 interface enhancements

Java 8 tried to solve some of the design concerns around the interfaces, if not designed correctly interfaces lead to the constant change of classes.

4.1. The change

Prior to java 8, interfaces are designed to define a contract. They had only abstract methods and final constants. With Java 8 interfaces have got a facelift. Now interfaces can have default and static methods (definitions). Default methods can be overridden. Whereas, static methods can’t be overridden. All the classes implementing interface should provide definition of all the methods in the interface. For some reason, if the designers had to change the interface, then all the implementing classes are affected. They all have to provide a definition for the new method. Java 8’s interface default and static methods provide a way to overcome this problem.

4.2. Java 8 interface example

Below interface, MobileInterface is an example demoing the Java 8 interface enhancements

/**
 * @author: Santosh Balgar Sachchiananda
 * This example shows the Java8 interface default methods
 */

public interface MobileInterface {

    /**
     * Java8 adds capability to have static method in interface.
     * Static method in interface Can't be overridden
     */
    public static void printWelcomeMessage() {
        System.out.println("***STATIC METHOD*** Welcome!!");
    }
    /*
     * Java8 adds capability of providing a default definition of method in an interface.
     * Default method can be overridden by the implementing class
     */
    default void makeACall(Long number) {
        System.out.println(String.format("***DEFAULT METHOD*** Calling ...... %d", number));
    }
    /*
     * Regular interface method, which every class needs to provide a definition
     */
    public void capturePhoto();
}

Class MobileInterfaceDemo is the driver program. BasicPhone and SmartPhone classes implement the interface MobileInterface and override the methods from MobileInterface.

  • BasicPhone overrides only the mandatory abstract method capturePhoto()
  • SmartPhone class overrides default method makeACall() and the mandatory abstract method capturePhoto()
/**
 * BasicMobile class provides definition only for mandatory abstract method
 * Need to provide definition for capturePhoto()
 * Whereas, makeACall() takes the default implementation
 */

class BasicPhone implements MobileInterface {
    @Override
    public void capturePhoto() {
        System.out.println("***BASIC PHONE*** Cannot capture photo");
    }
}

/**
 * SmartPhone class overrides both default method and abstract method
 * Provides definition for both makeACall() and capturePhoto() methods
 */
class SmartPhone implements MobileInterface {

    @Override
    public void makeACall(Long number) {
        System.out.println(String.format("***SMART PHONE*** Can make voice and video call to number .... %d", number));
    }

    @Override
    public void capturePhoto() {
        System.out.println("***SMART PHONE*** Can capture photo");
    }
}

/**
 * MobileInterfaceDemo is the driver class
 */
public class MobileInterfaceDemo {
    public static void main(String[] args) {
        MobileInterface basicPhone = new BasicPhone();
        MobileInterface smartPhone = new SmartPhone();

        // Calls static method of interface
        MobileInterface.printWelcomeMessage();
        System.out.println("********************** BASIC PHONE ************************");
        // Calls default implementation of interface
        basicPhone.makeACall(1234567890L);
        // Calls abstract method of interface
        basicPhone.capturePhoto();

        System.out.println("********************** SMART PHONE ************************");
        // Calls overridden implementation of makeACall()
        smartPhone.makeACall(1234567890L);
        // Calls abstract method of interface
        smartPhone.capturePhoto();
    }
}

The output from the MobileInterfaceDemo,

Interface vs Abstract Class Java - MobileInterfaceDemo
MobileInterfaceDemo

5. Guidelines to use interfaces and abstract classes

In real-world project projects if you are defining a contract which you want all the implementing classes to adhere to, then go for an interface. Interfaces are the best way to define the contract and concrete class can extend behaviors from another contract class. A classic example is Java threads.

If the use-case is to design a dynamic application whose features are to be extended in the near future and the requirement is to exhibit some concrete behavior then go for an abstract class. The caveat is, the concrete class cannot inherit behavior by extending any other class.

6. Instructions to run the code

Code download link is provided in the download section. Code has been written using IntelliJ Idea IDE. Unzip the attached code an import it as a Java project in IntelliJ. Choose the class with the main method (InterfaceDemo, BrandAPhoneDemo), right-click and run.

7. Download the Source Code

Download
You can download the full source code of this example here: Interface vs Abstract Class Java Example

Santosh Balgar

He is a Software Engineer working in an industry-leading organization. He has completed his bachelors from Visweswaraya Technological University. In his career, he has worked in designing and implementing various software systems involving Java/J2EE, Spring/ Spring Boot, React JS, JQuery, Hibernate and related database technologies. He loves to share his knowledge and always look forward to learning and explore new technologies. He loves to spend his free time with his family. He enjoys traveling and loves to play cricket.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button