Inheritance

 

Introduction:

Inheritance is one of the foundations of OOP. Inheritance allows you to create generic objects that define the state and behavior of all related objects. These generic traits (states and behaviors) can then be inherited by subclasses so that these variables and methods do not have to be re-written.

 

The Basics:

To create a subclass that inherits variable and methods of a superclass you use the keyword extends.  Examine the example below:

 

 

Figure 1

 

The output file is shown below:

 

 

Figure 2

 

As can be seen, the subclass subObject includes all of the variables and methods of the superclass. In fact, the subclass can refer to these variables directly because it will have its own copy of these variables and methods. The last line of the program shows this: the variables superObject.a and superObject.b are unchanged by the assignments of subObject.a and subObject.b.

 

In java, a subclass inherits all of the members in its superclass that are accessible to that subclass unless the subclass explicitly hides a member variable or overrides a method. Note that constructors are not members and are not inherited by subclasses.

 

The following list itemizes the members that are inherited by a subclass:

 

1.      Subclasses inherit those superclass members declared as public or protected.

2.      Subclasses inherit those superclass members declared with no access specifier as long as the subclass is in the same package as the superclass.

3.      Subclasses don't inherit a superclass's member if the subclass declares a member with the same name.

a.       Variables: the member variable in the subclass hides the one in the superclass.

b.      Methods: the method in the subclass overrides the one in the superclass.

 

The keyword “super”:

The keyword super can be used in two ways. The first is a call to the constructor of the superclass for the subclass. The second is the explicit use of the superclass’s members.

Constructor calls:

Let’s say, for example, that we wanted to extend the box class created in earlier topics to include a variable for weight. Below is a statement that would do this:

 

 

Figure 3

 

If we now want to use the box constructors to create instances of the new object we would use the super keyword to do so. This is a very efficient way to do this. The only alternative would be to duplicate all of the code for the box constructors (there were three: different side lengths, no initialization, and a cube). Below is an example of how to do this (refer to the box class example in the previous topic):

 

 

Figure 4

 

Note: To do this, super( ) must be the first statement within the subclass’s constructor.

 

Superclass Members:

There are many times that a subclass will want to hide one of the variables of a superclass. It does this by having a variable of the same name. If the programmer then wants to reference the superclass’s instance variable, the keyword super must be used. Consider the following example:

 

 

Figure 5

 

This program outputs the following statements:

a in the Superclass = 10

and a in the subclass = 20

 

super  can also be used to call overridden methods from the superclass.

 

You can create a class hierarchy with as many levels of superclass/subclass as you would like, or as many as would make sense. Each successive subclass created inherits all of the variables and methods from the ancestors in the superclasses. For example, let’s say you created a class hierarchy as shown below:

 

 

 

Figure 6

 

In this example, human would inherit all of the attributes and behaviors (variables and methods) of the biped, the land, and the mammal classes. In this way, the highest class in the hierarchy is the most generalized, while the class lowest in the hierarchy is the most specialized. This also reduces the amount of code needed. For instance, all mammals breathe air. All levels of the above hierarchy would inherit this method so that code would not have to be re-written. On the other hand, only the human class would need a method for driving a car.

 

When the constructors are called for such a hierarchy, the constructor for the highest level is executed first, and continues down the chain until the most specialized constructor is called. This happens because the higher levels do not know the implementations being defined in the lower levels.

 

Method Overriding:

There will be many reasons that you will want to override an ancestor’s method. To override an ancestor’s method, create a new method in the subclass with the exact same name and type signature. If this is done, the subclass’s method will be called in place of the ancestor’s method  - it will be overridden. If then you have a need to call the ancestor’s method, use the super keyword. For example:

 

 

Figure 6

 

As can be seen in the output below, the overriding method (displayVars()) in the subclass is the method that was called – not the overridden method in the superclass.

 

 

Figure 7

 

To access the displayVars() method in the superclass you would have to do one of two things:

1.      Call the superclass’s method from the subclass displayVars() method using the keyword supersuper.displayVars();  or

2.      Create a superObject in the OverEx class and call it explicitly: superObject.displayVars();

 

Method overriding occurs only if:

1.      The names of the two methods are identical, and

2.      The type signature is identical

 

Suppose we changed the displayVars() method in the subclass declaration to include passing a String object as in:

 

 

Figure 8

 

In this case the type signature of the two methods would be different, so the new method (shown above in Figure 8) would overload the superclass’s method – not override it.

 

Dynamic Method Dispatch:

Dynamic Method Dispatch is a fancy name for a powerful java implementation of polymorphism. It amounts to a run-time decision of the JVM regarding which method to execute based on a reference variable instead of explicit statements as shown above. Recall that a superclass reference variable may refer to a subclass object. When an overridden method is called through a superclass reference variable, the JVM determines which method to execute (run-time) based on the type of object being referenced at the time. For example:

 

 

Figure 9

 

Abstract Classes:

There will be situations in which you will want to create a framework for subclasses, but not fully implement them. This will happen when a superclass cannot create a meaningful implementation of a method. In this case you will have methods that must be overridden by a subclass, because the superclass does not provide the implementation. You can save a lot of debugging time in large projects by simply declaring an abstract method in the superclass. If a method is declared an abstract method – it must be overridden or you will generate compile-time errors.

 

To declare an abstract method:

 

 

Figure 10

 

There are a few limitations and restrictions that must be observed:

1.      Any class that contains one or more abstract methods must also be declared abstract.

2.      There can be no instances of an abstract class, but it may have a reference.

3.      You cannot declare abstract constructors

4.      You cannot declare abstract static methods

5.      A subclass of an abstract class must implement all of the ancestor’s methods or be declared abstract itself.

 

Here is an example:

 

 

Figure 11

 

The output of this program is shown below in Figure 12:

 

 

Figure 12

 

final:

The keyword final was used earlier to create constants for java programs. The keyword final has two other uses:

1.      Methods declared as final cannot be overridden.

2.      Classes Declared as final cannot have subclasses.

 

The Object Class:

All objects in java are subclasses of the class Object and as such inherit many capabilities in java that they may not otherwise have. This means that a reference variable of type Object can refer to any other object. And, because arrays and Strings are objects in java, a reference variable of type Object can refer to any array or String.

 

Object defines the following methods that are inherited by all objects created in java:

 

 


Send comments to: SJKuyath@uncc.edu
Copyright Stephen J Kuyath, UNC-Charlotte
last modified: January 12, 2002