DEV Community

nadirbasalamah
nadirbasalamah

Posted on

Java Tutorial - 10 Polymorphism

Introduction

In object oriented programming, there is a principle called polymorphism. Polymorphism means a behavior is implemented differently by many classes. For example, human and cat entity has a walk behavior but the walk implementation is different. The human walks with two legs whether the cat walks with four legs.

Creating an Abstract Class

Abstract class is a class that has a abstract method and complete method. Abstract method is a method that doesn't have any implementation. This is the basic syntax of creating abstract class.

modifier abstract class class_name {
    // code..
}
Enter fullscreen mode Exit fullscreen mode

This is the basic syntax of creating abstract method.

modifier abstract return_type method_name(parameters);
Enter fullscreen mode Exit fullscreen mode

In this example, there are two classes that created called Car as abstract class and RaceCar as class that extends to Car class.

Car Class.

public abstract class Car {
    private String manufacturer;
    private String model;

    public Car(String manufacturer, String model) {
        this.manufacturer = manufacturer;
        this.model = model;
    }

    // create an abstract method
    public abstract void run();

    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }
}

Enter fullscreen mode Exit fullscreen mode

RaceCar Class.

public class RaceCar extends Car {
    private String teamName;

    public RaceCar(String manufacturer, String model, String teamName) {
        super(manufacturer, model);
        this.teamName = teamName;
    }

    // implement run() from Car class
    @Override
    public void run() {
        System.out.println("Running with racing spec");
    }

    public String getTeamName() {
        return teamName;
    }

    public void setTeamName(String teamName) {
        this.teamName = teamName;
    }
}

Enter fullscreen mode Exit fullscreen mode

Based on the code above, the Car class contains abstract method called run() that is implemented specifically inside RaceCar class.

This is the example of RaceCar class usage in main class.

Main class.

public class MyApp {
    public static void main(String[] args) {
        RaceCar raceCar = new RaceCar("Porsche","911 GT3","Manthey Racing");
        raceCar.run();
    }
}

Enter fullscreen mode Exit fullscreen mode

Output

Running with racing spec

Enter fullscreen mode Exit fullscreen mode

Based on the code above, the run() method is called from raceCar object that created from RaceCar class.

The object can be created from the abstract class. This is the example of creating object from abstract class called Car class.

public class MyApp {
    public static void main(String[] args) {
        Car myCar = new Car("Ford","Puma") {
            // implement abstract method
            @Override
            public void run() {
                System.out.println("running with factory spec");
            }
        };

        // call the method
        myCar.run();
    }
}

Enter fullscreen mode Exit fullscreen mode

Output

running with factory spec

Enter fullscreen mode Exit fullscreen mode

Based on the code above, the abstract method is implemented directly.

If the abstract class has many abstract methods, a class that extends to the abstract class have to implement all the abstract methods.

Creating an Interface

Interface is a class that only allows abstract methods. The interface is useful to define a contract that can be used later by many classes. This is the basic syntax of creating interface.

modifier interface interface_name {
    // define some abstract methods..
}
Enter fullscreen mode Exit fullscreen mode

To create a method in interface, the abstract keyword is not needed.

In this example, the interface called Driveable is created. The abstract method called run() is created inside this interface.

public interface Driveable {
    // create an abstract method
    public void run();
}

Enter fullscreen mode Exit fullscreen mode

This interface is implemented by Car class. If the interface is implemented by a class, all the methods inside interface have to be implemented.

public class Car implements Driveable {
    private String manufacturer;
    private String model;
    private double performanceRating;

    public Car(String manufacturer, String model, double performanceRating) {
        this.manufacturer = manufacturer;
        this.model = model;
        this.performanceRating = performanceRating;
    }

    // implement run() method from Driveable interface
    @Override
    public void run() {
        System.out.println("Running with factory spec");
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public double getPerformanceRating() {
        return performanceRating;
    }

    public void setPerformanceRating(double performanceRating) {
        this.performanceRating = performanceRating;
    }
}

Enter fullscreen mode Exit fullscreen mode

Based on the code above, the @Override annotation is used to implement a method that specified in an interface.

In Java, a single class can implements many interfaces. In this example, the Upgradeable interface is implemented by Car class.

Upgradeable interface.

public interface Upgradeable {
    public void upgrade(double number);
}

Enter fullscreen mode Exit fullscreen mode

Car class.

public class Car implements Driveable,Upgradeable {
    private String manufacturer;
    private String model;
    private double performanceRating;

    public Car(String manufacturer, String model, double performanceRating) {
        this.manufacturer = manufacturer;
        this.model = model;
        this.performanceRating = performanceRating;
    }

    // implement run() method from Driveable interface
    @Override
    public void run() {
        System.out.println("Running with factory spec");
    }

    // implement upgrade() method from Upgradeable interface
    @Override
    public void upgrade(double number) {
        double upgradedPR = getPerformanceRating() + number;
        setPerformanceRating(upgradedPR);

        System.out.println("Car upgraded");
        System.out.println("The performance rating now is: " + getPerformanceRating());
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public double getPerformanceRating() {
        return performanceRating;
    }

    public void setPerformanceRating(double performanceRating) {
        this.performanceRating = performanceRating;
    }
}

Enter fullscreen mode Exit fullscreen mode

Main class

public class MyApp {
    public static void main(String[] args) {
        Car car = new Car("Renault","Clio", 12.5);

        // call the methods
        car.run();
        car.upgrade(10.5);
    }
}

Enter fullscreen mode Exit fullscreen mode

Output

Running with factory spec
Car upgraded
The performance rating now is: 23.0

Enter fullscreen mode Exit fullscreen mode

Based on the code above, the run() and upgrade() methods is called.

The default method is available in interface. Default method basically is used to define the default method's implementation if the method is not implemented by class. This is the basic syntax of default method in interface.

modifier default return_type method_name(params) {
    // code..
}
Enter fullscreen mode Exit fullscreen mode

In this example, the default method called work() in Workable interface is created. Then, this interface is implemented by Employee class.

Workable interface.

public interface Workable {
    // define default method called work()
    default void work() {
        System.out.println("working...");
    }
}

Enter fullscreen mode Exit fullscreen mode

Employee class.

public class Employee implements Workable{
    private String name;

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Enter fullscreen mode Exit fullscreen mode

Main class.

public class MyApp {
    public static void main(String[] args) {
        Employee employee = new Employee("John Doe");
        employee.work();
    }
}

Enter fullscreen mode Exit fullscreen mode

Output.

working...

Enter fullscreen mode Exit fullscreen mode

Based on the code above, the work() method is not implemented explicitly by Employee class so the default method inside Workable interface is used.

Sources

  • Learn more about abstract class in this link.

  • Learn more about interface in this link.

I hope this article is helpful for learning the Java programming language. If you have any thoughts or comments you can write in the discussion section below.

Top comments (0)