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();
}
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");
}
}
public class ItalianPerson extends Person {
@Override
public void sayHello() {
System.out.println("Ciao");
}
}
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();
}
}
that will print:
Ciao
Hola
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();
}
}
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);
}
}
that again will print:
Ciao
Hola
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)