This question already has answers here:
Closed 3 years ago.
Imagine that we have a class Animal
that extends to three other classes: Dog
, Cat
, Bird
.
This animal class has a talk()
and move()
function. The talk function outputs "Animal talking" and the move function outputs "Animal moving".
For a dog, this is "Dog moving" and "Dog eating". For the Cat
and Bird
class, this difference is paralleled "Cat moving" etc.
Now, because of polymorphism, if I do
Animal charlietheBird = new Bird()
and then call in
charlietheBird.talk()
it will output
Bird talking
because the output is determined at runtime since the compiler knows that charlie is a type of Animal
of the class Bird
.
HOWEVER!!
I can simply do
Bird charlietheBird = new Bird();
and then calling charlietheBird.poop();
will give the same output, because the
method would have been overridden.
What can polymorphism do that inheritance can't?
The real advantages of Polymorphism can be seen at runtime rather than compile time. Polymorphism allows you to substitute one implementation for another without the need to change the code that uses it. Let's take your example of the Animal
hierarchy. Let's say you have a Vet
that knows how to perform health checkups on any animal (Yup he's a supervet).
class Vet {
private Animal animal;
public Vet(Animal animal) {
this.animal = animal;
}
public void perfromCheckup() {
animal.talk();
animal.poop();
}
}
You can now say :
Vet vetWithBird = new Vet(new Bird());
Vet vetWithDog = new Vet(new Dog());
vetWithBird.performCheckup();
vetWithDog.performCheckup();
Notice how you can tell the Vet
to perform a checkup on a Bird
or a Dog
or any other animal for that matter without needing to change your Vet
class. At runtime, the Dog
would bark when it goes for a checkup and the Bird
would tweet when it goes for a checkup. Imagine if instead of Animal
, the Vet
had a Bird
reference :
class Vet {
private Bird bird;
public Vet(Bird bird) {
this.bird = bird;
}
public void perfromCheckup() {
bird.talk();
bird.poop();
}
}
The poor Vet
is now only going to be able to work with a Bird
. Tell your Vet
to work with a Dog
and he will reject this right away.
Vet vetWithBird = new Vet(new Bird()); //Works fine. Vet likes birds.
Vet vet = new Vet(new Dog())// compilation error. Sorry I don't like dogs.
In summary, Polymorphism allows you to substitute subclass instances where a super-class reference is used. Inheritance allows you to inherit code from a parent class and possibly redefine that behavior in subclasses so that your code can take advantage of it at runtime through Polymorphism
Inheritance supports Polymorphism but Polymorphism does not depend on Inheritance.
You gave an example how to achief Polymorphism via Inheritance.
But you could look at it differently:
There is an interface for the concept of moving:
interface Movable{
void move();
}
Animals may implement this interface:
class Dog implements Movable {
@Override
public void move(){
// move the animal
}
}
but some fungis can also move:
class SlimeMold implements Movable {
@Override
public void move(){
// move the animal
}
}
There is hardly to find an "is a" relationship between those two which could be expressed by inheritance, but when both implement the same interface we can still apply Polymorphism on them:
Collection<Movable> movables = new HashSet<>();
movables.add(new Dog());
movables.add(new SlimeMold());
for(Movable movable : movables)
movable.move();
Inheritance refers to a feature of Java programming that lets you create classes that are derived from other classes. A class that's based on another class inherits the other class. The class that is inherited is the parent class, the base class, or the superclass.
Polymorphism refers to a programming language's ability to process objects differently depending on their data type or class. More specifically, it is the ability to redefine methods for derived classes.
You can find more information in Objects and Java by Bill Venners Chapter 7:
Polymorphism and Interfaces