DEV Community

Aldo Telese
Aldo Telese

Posted on • Edited on

Polymorphism and abstract class easily explained in Java

Polymorphism is one of the main concepts behind OOP, together with encapsulation and inheritance. Despite its definition being pretty straightforward, you might struggle in understanding the reasons why it is used and the benefits it can lead to.

Polymorphism literally means that an object can take on many forms.

Here is a very simple example of a scenario where we can benefit from using polymorphism. We are going to make use of an abstract class for the purpose, taking the opportunity to explain this concept as well.

Let's say we want to make a class representing a human saying hello in its own language.

Since saying hello is very specific to the language spoken by the person, a good candidate to start with would be in fact an abstract class called Person, containing a method called sayHello to be implemented by concrete classes extending it (an EnglishPerson, an ItalianPerson, a SpanishPerson, etc.)

Here is our Person class:

public abstract class Person {
    public abstract void sayHello();
}
Enter fullscreen mode Exit fullscreen mode

As you can see an abstract class generally contains one or more methods declared without an implementation.
Why? Because the class is too generic to have a single implementation, and it is expected to be extended by other classes that will then be required to implement such abstract method(s).

Let's create two more classes now: SpanishPerson and ItalianPerson:

public class SpanishPerson extends Person {
    @Override
    public void sayHello() {
        System.out.println("Hola");
    }
}
Enter fullscreen mode Exit fullscreen mode
public class ItalianPerson extends Person {
    @Override
    public void sayHello() {
        System.out.println("Ciao");
    }
}
Enter fullscreen mode Exit fullscreen mode

We have created two concrete classes extending our abstract class and implementing the single abstract method that was declared.

Now we can leverage polymorphism by writing this:

public class HelloDemo {
    public static void main(String[] args) {
        Person mattia = new ItalianPerson();
        Person dolores = new SpanishPerson();

        mattia.sayHello();
        dolores.sayHello();
    }
}
Enter fullscreen mode Exit fullscreen mode

that will print:

Ciao
Hola
Enter fullscreen mode Exit fullscreen mode

Basically with polymorphism we are able to assign a reference of a superclass to an instance of a subclass.
In our case, mattia and dolores are two references of the superclass Person, but in practice they are pointing to objects of type ItalianPerson and SpanishPerson, respectively.

To better understand the power of such concept let's introduce a new Greeter class containing a method that accepts an argument of type Person that will invoke its sayHello method as before.

public class Greeter {
    public void greet(Person person) {
        person.sayHello();
    }
}
Enter fullscreen mode Exit fullscreen mode

Instead of creating two (or more) different greet methods, one with a parameter of type ItalianPerson and the other one with a parameter of type SpanishPerson, we can leverage polymorphism by using a single method with a parameter of the abstract superclass Person to which we can pass either an ItalianPerson or a SpanishPerson instance, just as shown below:

public class HelloDemo {
    public static void main(String[] args) {
        Person mattia = new ItalianPerson();
        Person dolores = new SpanishPerson();

        Greeter greeter = new Greeter();
        greeter.greet(mattia);
        greeter.greet(dolores);
    }
}
Enter fullscreen mode Exit fullscreen mode

that again will print:

Ciao
Hola
Enter fullscreen mode Exit fullscreen mode

making our code more extensible, reusable and clean.

Hope you enjoyed this short explanation of one of the core concepts of object oriented programming.
Please feel free to leave a comment for any feedback.

See you soon

Top comments (0)