This question is taken from an AP Computer Science practice test.
public class Bird
{
public void act()
{
System.out.print("fly");
makeNoise();
}
public void makeNoise()
{
System.out.print("chirp");
}
}
public class Dove extends Bird
{
public void act()
{
super.act();
System.out.print("waddle");
}
public void makeNoise()
{
super.makeNoise();
System.out.print("coo");
}
}
Suppose the following declaration appears in a class other than Bird or Dove:
Bird pigeon = new Dove();
What is printed as a result of the call pigeon.act()
?
I thought the answer would be "fly chirp", but the textbook says that the answer is "fly chirp coo waddle". I thought that 'pigeon' could only access methods available in Bird? I was under the impression that, if the user wanted to access methods in Dove, 'pigeon' would have to be cast to Dove.
Would Bird pigeon = new Bird();
give the same output? How about Dove pigeon = new Dove();
?
Long story short, when you access act
method of pigeon
, its override from Dove
is called.
I thought that 'pigeon' could only access methods available in Bird?
That is certainly true, at least, for situations when no casting is applied. However, method act
is available on the class Bird
, the statically known type of pigeon
, so the call compiles fine.
However, accessing methods is only about being able to call them. What methods do when you call them is decided at runtime based on the dynamic type of pigeon
. This is where method overriding comes into play, because Dove
overrides Bird
's methods, but in addition it also calls Bird
's methods. That is why the code hits all four printouts.
Would
Bird pigeon = new Bird();
give the same output?
No, the output would be different, because in this case both dynamic and static types of pigeon
would be the same, i.e. Bird
, so only Bird
's implementations would be invoked.
Dove
does override the methods act
and makeNoise
of class Bird
. Overriding means changing the behavior of a method visible to the sub-class, (in your case Dove
). Methods are visible to a sub-class if they have a public
or protected
access modifier or if they have a package private
access modifier and the sub-class belongs to the same package as the super-class does. pigeon
is an instance of Dove
.pigeon.act()
results in calling Dove.act
.Dove.act
calls super.act
which is Bird.act
.Bird.act
prints fly
and calls makeNoise
on pigeon
resulting in calling Dove.makeNoise
.Dove.makeNoise
calls super.makeNoise
which is Bird.makeNoise
.Bird.makeNoise
print chirp
.Dove.makeNoise
prints coo
after calling super.makeNoice
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With