If a derived class extends a base class, it is not only considered an instance of the derived class, but an instance of the base class as well. The compiler knows that all the features of the base class were inherited, so they are still there to work in the derived class (keeping in mind that they may have been changed).
This demonstrates what is known as an Is A relationship - a derived class object is A base class instance as well.
It is an example of polymorphism; that one reference can store several different types of objects. For example, in the arcade game example, for any character that is used
in the game, an
Entity reference variable could be used, so
that at runtime, any subclass can be instantiated to store in that variable.
Entity shrek = new Ogre(); Entity merlin = new Wizard();
Playablevariable could be used.
Playable charles = new Prince();
When this is done, however, the only elements immediately available through the reference are those know to exist; that is, those elements defined in the reference type object. Note that:
merlin.moveTo()would be legal, since that element is guaranteed to be there.
merlin.castSpell()would not be legal, since the definition of
Entitydoes not include it, even though the actual object does have that capability.
Entity x; if (Math.random() < 0.5) x = new Wizard(); else x = new Troll();There is no way the compiler could determine what type of object would actually be created.
charles, are probably not good choices: presumably we know
shrekis an ogre, and always will be, so the type might as well be
Ogre(unless, of course, he could transmogrify into something else during the game ...).
When a method
is called through a reference, the JVM looks to the actual class of the instance
to find the method. If it doesn't find it there, it backs up to the ancestor
class (the class this class extended) and looks there (and if it doesn't
find it there, it backs up again, potentially all the way to
Sooner or later, it will find the method, since if it wasn't defined somewhere in the chain of inheritance, the compiler would not have allowed the class to compile.
In this manner, what you could consider the most advanced (or most derived) version of the method will run, even if you had a base class reference.
So, for our arcade game, an
Entity reference could hold a
and when the
moveTo method is called, the
moveTo will run.
An interesting aspect of dynamic method invocation is that it occurs even if the method is called from base class code. If, for example:
moveTomethod called its own
Ogreclass didn't override
moveTo, but did override
Ogrestored in an
moveTomethod was called.
Entity version of
moveTo would run, but its
toString would invoke
toString method from