Contact Us or call 1-877-932-8228


Inheritance and References

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();
  • For the player's character, a Playable variable 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:

  • The compiler decides what to allow you to do with the variable based upon the type declared for the variable.
  • merlin.moveTo() would be legal, since that element is guaranteed to be there.
  • merlin.castSpell() would not be legal, since the definition of Entity does not include it, even though the actual object does have that capability.
  • The following example gives a hint as to why this is the case:
    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.
  • The variables names above, shrek, merlin, and charles, are probably not good choices: presumably we know shrek is 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 ...).

Dynamic Method Invocation

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 Object).

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 Wizard, and when the moveTo method is called, the Wizard version of 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:

  • The Entity class moveTo method called its own toString method.
  • The Ogre class didn't override moveTo, but did override toString.
  • For an Ogre stored in an Entity variable, the moveTo method was called.

The Entity version of moveTo would run, but its call to toString would invoke the toString method from Ogre!