Overview

 

In this post, we’re gonna take a look at what Polymorphism is in Java. During my years working with Java and with few interview I done to some people, I encounter that this topic is a bit confusing to some extent. So let’s dig a little bit on what this concept means and how is used in Java.

 

What is Polymorphism?

In Java, and in more general Object Oriented paradigms, exists a group of 4 main features that help define an object-oriented model. These features are:

  • Abstraction
  • Encapsulation
  • Inheritance
  • Polymorphism

In this model an application is to be built around Objects, it’s properties or state and it’s behavior to perform actions.

Some definition of this term is:

The condition of occurring in several different forms

In biology the term is coined as:

“The occurrence of different forms among the members of a population or colony, or in the life cycle of an individual organism.”

 

These are some cool definitions. But what it means in Java?. Well, the definition is quite similar.

In OOP, Polymorphism is the ability of an Object to behave like others in its hierarchical tree, meaning that an Object can be replaced anywhere a superclass is needed, and this object can behave like its parent. So, it can take several different forms.

Let’s look at some examples to visualize this concept.

 

Animals model

Let’s say we want to model the animals hierarchy (yes, I know, another post with animals, but animals are cool, isn’t)

 

Let’s model this into Java

Animal.java

package com.darksideofhtedev.animals;

public class Animal {

    public void whoAreYou(){
        System.out.println("I'm a animal");
    }
}

Canine.java

package com.darksideofhtedev.animals;

public class Canine extends Animal {

    public void whoAreYou(){
        System.out.println("I'm a Canine");
    }
}

Dog.java

package com.darksideofhtedev.animals;

public class Dog extends Canine {

    public void whoAreYou(){
        System.out.println("I'm a Dog");
    }
}

Wolf.java

package com.darksideofhtedev.animals;

public class Wolf extends Canine {

    public void whoAreYou(){
        System.out.println("I'm a Wolf");
    }
}

Bulldog.java

package com.darksideofhtedev.animals;

public class Bulldog extends Dog {

    public void whoAreYou(){
        System.out.println("I'm a Bulldog");
    }
}

Chihuahua.java

package com.darksideofhtedev.animals;

public class Chiguagua extends Dog {

    public void whoAreYou(){
        System.out.println("I'm a Chihuahua");
    }
}

GreyWolf

package com.darksideofhtedev.animals;

public class GreyWolf extends Wolf {

    public void whoAreYou(){
        System.out.println("I'm a GreyWolf");
    }
}

 

Ok, that’s was a lot of code. Now let’s test it and see how Polymorphism works

 

Polymorphism in action

In our main class, the one with the main() method, lest writing some methods to help us test this. So first one should be like this.

    public static void sayWhoYouAre(Animal animal){

        animal.whoAreYou();
    }

 

This method expects an Animal as a parameter. But let’s pass some of our animals. Our main() method should look like this.

public static void main( String[] args ) {

        Canine canine = new Canine();
        Dog dog = new Dog();
        Bulldog bulldog = new Bulldog();

        sayWhoYouAre(canine);
        sayWhoYouAre(dog);
        sayWhoYouAre(bulldog);
}

If we run it, we should have a console output

I'm a Canine
I'm a Dog
I'm a Bulldog

As you can see, even when the method sayWhoYouAre() expects an animal as a parameter, we can pass any of its subclasses, and the specific whoAreYou() method is invoked. Polymorphism is applied to every subclass of animal, that is to say, all of these can behave as an animal because that’s what they are.

Lest overload this method, this time it expects a Dog parameter.

public static void sayWhoYouAreDog(Dog dog){

     dog.whoAreYou();
}

Now if we test it with this main() method we’ll see some interesting things.

public static void main( String[] args ) {

    Animal animal = new Animal();
    Canine canine = new Canine();
    Dog dog = new Dog();
    Bulldog bulldog = new Bulldog();
    Wolf wolf = new Wolf();
    Chiguagua chiguagua = new Chiguagua();
    GreyWolf greyWolf = new GreyWolf();


    sayWhoYouAreDog(animal);
    sayWhoYouAreDog(canine);
    sayWhoYouAreDog(dog);
    sayWhoYouAreDog(bulldog);
    sayWhoYouAreDog(wolf);
    sayWhoYouAreDog(chiguagua);
    sayWhoYouAreDog(greyWolf);

}

First thing first. Polymorphism works only with objects that pass the “IS-A” test, in other words, they have an inheritance relationship. “IS-A” test works only up through the inheritance tree. In the above code, lines 12,13,16 and 18 will not compile, that’s because they do not pass the “IS-A” test with a Dog object.

Think about it for a minute, an Animal IS NOT a Dog, same for a wolf, a Wolf IS NOT a Dog. (Base on our design model).

For the rest of the lines, it compiles just fine and prints:

I'm a Dog
I'm a Bulldog
I'm a Chihuahua

Same thing applies when the “IS-A” test happens when the relationship is with Interfaces.

 

Summary

So we have looked at what Polymorphism is, play around with some code and see how this works. You need to remember that Polymorphism works with Inheritance and that this work all the way up the hierarchy tree. With this feature, you can pass around objects of some type to behave like others giviong you more flexibility when writing code.