Polymorphism vs Inheritance

Suppose I have two classes: Animal and Dog. Dog is a subclass of Animal. I do the following code:

Animal a = new Dog();

Now I can call methods of the Dog class through the a variable.

But my question is this: if I can call all of Animal's methods through the Dog objects (inheritance) than why should I use the polymorphism principle? I can just declare:

Dog d = new Dog();

With this declaration can use all of Animal's methods and Dog methods. So why use polymorphism? Thank you very much for your answer.

Answers


In Java, the concepts of polymorphism and inheritance are "welded together"; in general, it does not have to be that way:

  • Polymorphism lets you call methods of a class without knowing the exact type of the class
  • Inheritance lets derived classes share interfaces and code of their base classes

There are languages where inheritance is decoupled from polymorphism:

  • In C++ you can inherit a class without producing polymorphic behavior (i.e. do not mark functions in the base class with virtual)
  • In Objective C you can implement a method on an unrelated class, and call it from a place that knows only the signature of the method.

Going back to Java, the reason to use polymorphism is decoupling your code from the details of the implementation of its counter-parties: for example, if you can write a method Feed(Animal animal) that works for all sorts of animals, the method would remain applicable when you add more subclasses or implementations of the Animal. This is in contrast to a Feed(Dog dog) method, that would be tightly coupled to dogs.

As far as the

Dog d = new Dog();

declaration goes, there is no general reason to avoid this if you know that the rest of your method deals specifically with dogs. However, in many cases the later is not the case: for example, your class or your methods would often be insensitive to the exact implementation, for example

List<Integer> numbers = new ArrayList<Integer>();

In cases like that, you can replace new ArrayList<Integer>() with new LinkedList<Integer>(), and know that your code is going to compile. In contrast, had your numbers list been declared as ArrayList<Integer> numbers, such switchover may not have been a certainty.

This is called "programming to an interface". There is a very good answer on Stack Overflow explaining it.


You can have other implementations of the Animal class, such as Cat. Then you can say

Animal a = new Dog();
Animal b = new Cat();

You can call methods of the Animal class without caring which implementation it really is, and polymorphism will call the correct method. E.g.

a.speak();  // "Woof"

b.speak();  // "Meow"

Really, it's not "Polymorphism vs Inheritance" but "Polymorphism using Inheritance".


Polymorphism allows you to write a method that works for any Animal:

public void pet(Animal animal) {
   ...
}

This method would accept Dog, Cat, etc, including subclasses of Animal that are yet to be written.

If the method were to take Dog, it would not work for Cat etc.


If you are certain that it will always be a dog there is no reason for it. You might aswell use Dog d = new Dog(); as you described. But let's say you used a method instead of a constructor. The method returned an animal and you wouldn't know which implementation of animal you would get. You would still be able to use the same methods on the animal (even if it's a Dog, Elephant cat etc).

For extensibility purposes inheritance simplifies things. When you want to create an elephant or cat which also share some animal methods, You can easily get those by having animal as super class.


Normally the question you've asked is more similar to Inheritance vs Composition :) More "real life" example of why it's good to use polymorphism is for example usage of strategy design pattern. You can have many TaxPolicy implementation: UsaTaxPolicy, CanadaTaxPolicy, EuTaxPolicy, etc. If you have method calculateFinalPrice, which have to also calculate tax, then you inject the proper implementation and good calculation is executed, no matter you've passed Usa, Canada or Eu implementation.


inheritance is the dynamic polymorphism. I mean when you remove inheritance you can not override anymore.


Need Your Help

How to pass JVM arguments in SpringBOOT

spring spring-mvc spring-boot

I would like to pass JVM arguments in the main spring boot class where we will be starting the spring boot application.

Best way to unit test console c# app

c# unit-testing nunit

I have a simple console app. It's fired of with a normal main and the entire program recides in main. It uses the Command Line Parser Library. Then I have a second project in the solution containin...