This is an article about basic inheritance and polymorphism in Java Programming Language.
Let’s start by creating a class hierarchy based on animals in a zoo.
First we create the Animal base class.
The central idea is that we have a group of animals living inside a zoo.
This group of animals consists of Lions, Tigers, Cats, Hippos, Wolfs and Dogs.
They can do certain things like sleeping, roaming, making noise or eating.
Along with the things that they can do they also carry specific characteristics like the kind of food they prefer (meat or grass), how much hungry they are at a specific moment and their location in the zoo.
Their image too, is a key characteristic of every animal.
To formulate in a java class all these common characteristics, we decide to create an abstract class called Animal.
The following image is a diagram of the Animal abstract class :
And here you can see the code of the Animal class:
Animal class is very general so we declare this class as abstract.
The fact that the animal class is abstract does not prevent us from writing some methods that can be used in another class or preferably to a number of classes that are positioned below the Animal class in the inheritance tree.
Notice the two highlighted lines (77 and 78).
These abstract methods must be implemented (overridden) by some class below the animal class at the hierarchy tree.
At this point we can see two more great categories of animals that introduces some more common behaviour.
For example Felines (Lions, Tigers, Cats) tend to avoid others of their own kind when they move and Canines (Wolfs, Dogs) tend to move in packs.
We can use this fact to create a couple more of abstract classes.
Let’s see the application diagram and where is the position of these two new abstract classes:
And here is the code of the two abstract classes :
As you can see we override here the implementation we had provided in the parent Animal class.
Let’s see how this theory behaves in action with real objects.
I have created a small application for this article and here is the code :
If you check this code, you’ll see that at line 30 we create a new Hippo object.
You can see the Hippo class diagram and code right below :
As we see here the Hippo has its own implementations of makeNoise() and eat() methods, and thus it fulfils the obligation to provide concrete implementations of abstract methods that exist above him at the class hierarchy tree.
Now we can run a small application that I have been created for this article.
Here is the application code :
When we run this code we are getting the following result at the console window :
Inheritance in action<br />------------------------------------------------------<br />The wolf howls<br />The Canines move in packs<br />, and now that it is a wolf it is very dangerous for its prey<br />The wolf is eating MEAT<br />The animal sleeps</p><p>Polymorphism in action<br />------------------------------------------------------<br />The dog is eating GRASS<br />The Canines move in packs<br />The cat eats GRASS<br />The Felines avoid each other<br />The wolf is eating MEAT<br />The Canines move in packs<br />, and now that it is a wolf it is very dangerous for its prey<br />The hippo is eating GRASS<br />The animal is roaming<br />The lion is eating MEAT<br />The Felines avoid each other</p><p>Polymorphic arguments<br />------------------------------------------------------<br />The vet is giving a shot to Wolf<br />The wolf howls</p><p>Process finished with exit code 0
At line 18 the Hippo is using its own method but at the next line (19) the Hippo is using the generic roaming method from his parent Animal abstract class.
As you can see in my small program we can declare an object to be of any type above its class in the inheritance tree.
So with this array of Animal type we are getting very flexible because we can assign to the Animal variable any concrete object instance at runtime.
Now let’s turn our attention at the wolf object.
The rule here is that when you are calling an object method, the most specific version of the method is get executed.
You can see that in App2.java, lines 14-17.
Another thing to point here is that wolf’s own roam method is using its parent (Canine class) roam method by using the super keyword.
Check how this work by looking at the Wolf class diagram and code :
Let’s see now the complete inheritance tree and the rest of the various class code.
Finally we can use polymorphism to declare method arguments as a general type and then pass as an argument any concrete object that is of this type.
Check for example the Vet class.
We can send in any animal we want and as we saw at the console window posted before every animal reacts with a different noise!
That’s all for today.
See you at my next article when we will talk about interfaces.
PS : A link with the whole project code — > Java inheritance and polymorphism Github Project