Chapter 4
Chapter 4
Inheritance
4.1 Inheritance Basics
Inheritance is one of the cornerstones of object-oriented programming because it allows the
creation of hierarchical classifications. Using inheritance, you can create a general class that
defines traits common to a set of related items. This class can then be inherited by other, more
specific classes, each adding those things that are unique to it. In the terminology of Java, a class
that is inherited is called a super class. The class that does the inheriting is called a subclass. It
inherits all of the instance variables and methods defined by the super class and adds its own,
unique elements.
To inherit a class, you simply incorporate the definition of one class into another by using the
extends keyword. To see how, let’s begin with a short example. The following program creates a
super class called A and a subclass called B. Notice how the keyword extends is used to create a
subclass of A.
// A simple example of inheritance.
class A { B subOb = new B();
int i, j; // The superclass may be used by itself.
void showij() { superOb.i = 10;
System.out.println("i and j: " + i + " " + j); superOb.j = 20;
}} System.out.println("Contents of superOb: ");
class B extends A { superOb.showij();
int k; System.out.println();
void showk() { //The subclass has access to all public
System.out.println("k: " + k); members of its superclass.
} subOb.i = 7;
void sum() { subOb.j = 8;
System.out.println("i+j+k: " + (i+j+k)); subOb.k = 9;
}} System.out.println("Contents of subOb: ");
class SimpleInheritance { subOb.showij();
public static void main(String args[]) { subOb.showk();
A superOb = new A(); System.out.println();
System.out.println("Sum of i, j and k in subOb.sum();
subOb:"); }}
The output from this program is shown here:
Contents of superOb:
i and j: 10 20
Contents of subOb:
i and j: 7 8
k: 9
Sum of i, j and k in subOb:
i+j+k: 24
As you can see, the subclass B includes all of the members of its superclass, A. This is why
subOb can access i and j and call showij( ). Also, inside sum( ), i and j can be referred to
directly, as if they were part of B.
Even though A is a super class for B, it is also a completely independent, stand-alone class.
Being a super class for a subclass does not mean that the super class cannot be used by itself.
Further, a subclass can be a super class for another subclass.
The general form of a class declaration that inherits a super class is shown here:
class subclass-name extends superclass-name {
// body of class
}
You can only specify one super class for any subclass that you create. Java does not support the
inheritance of multiple super classes into a single subclass. You can, as stated, create a hierarchy
of inheritance in which a subclass becomes a super class of another subclass.
However, no class can be a super class of itself.
Although a subclass includes all of the members of its super class, it cannot access those
members of the super class that have been declared as private.
For example, consider the following simple class hierarchy:
/* In a class hierarchy, private members remain
private to their class.
This program contains an error and will not
compile.
*/
class A { total = i + j; // ERROR, j is not accessible
int i; // public by default here
private int j; // private to A }}
void setij(int x, int y) { class Access {
i = x; public static void main(String args[]) {
j = y; B subOb = new B();
}} subOb.setij(10, 12);
class B extends A { subOb.sum();
int total; System.out.println("Total is " +
void sum() { subOb.total);
}}
This program will not compile because the reference to j inside the sum( ) method of B causes
an access violation. Since j is declared as private, it is only accessible by other members of its
own class. Subclasses have no access to it.
4.1.2 A Super class Variable Can Reference a Subclass Object
A reference variable of a super class can be assigned a reference to any subclass derived from
that super class. You will find this aspect of inheritance quite useful in a variety of situations.
For example, consider the following:
// Box class is super class of BoxWeight
class RefDemo {
public static void main(String args[]) {
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box();
double vol;
vol = weightbox.volume();
System.out.println("Volume of weightbox is " + vol);
System.out.println("Weight of weightbox is " +weightbox.weight);
System.out.println();
// assign BoxWeight reference to Box reference
plainbox = weightbox;
vol = plainbox.volume(); // OK, volume() defined in Box
System.out.println("Volume of plainbox is " + vol);
/* The following statement is invalid because plainbox
does not define a weight member. */
// System.out.println("Weight of plainbox is " + plainbox.weight);
}}
Here, weightbox is a reference to BoxWeight objects, and plainbox is a reference to Box
objects.
Since BoxWeight is a subclass of Box, it is permissible to assign plainbox a reference to the
weightbox object.
It is important to understand that it is the type of the reference variable—not the type of the
object that it refers to—that determines what members can be accessed. That is, when a reference
to a subclass object is assigned to a super class reference variable, you will have access only to
those parts of the object defined by the super class. This is why plainbox can’t access weight
even when it refers to a BoxWeight object. If you think about it, this makes sense, because the
super class has no knowledge of what a subclass adds to it. This is why the last line of code in
the preceding fragment is commented out. It is not possible for a Box reference to access the
weight field, because Box does not define one.
4.2 Using super Keyword
Whenever a subclass needs to refer to its immediate super class, it can do so by use of the
keyword super. Super has two general forms. The first calls the super class constructor. The
second is used to access a member of the super class that has been hidden by a member of a
subclass. Each use is examined here.
Using super to call super class Constructor
A subclass can call a constructor method defined by its super class by use of the following form
of super.
super ( parameter-list );
Here, parameter-list specifies any parameters needed by the constructor in the super class. super
( ) must always be the first statement executer inside a subclass constructor.
To see how super ( ) is used, consider this improved version of the BoxWeight ( ) class:
// BoxWeight now uses super to initialize its Box attributes.
class BoxWeight extends Box {
double weight ; // weight of box
// Initialize width, height and depth using super ()
BoxWeight ( double w, double h, double d, double m ) {
super ( w, h, d); // call super class constructor
weight = m;
}}
Here, BoxWeight( ) calls super( ) with the parameters w, h and d. This causes the Box( )
constructor to be called, which initializes width, height and depth using these values.
BoxWeight no longer initializes these values itself. It only needs to initialize the value unique to
it: weight.
In the preceding example, super ( ) was called with three arguments. Since constructors can be
overloaded, super ( ) can be called using any form defined by the super class.
The Second use of super
The second form of super acts somewhat like this, except that it always refers to the super class
of the subclass in which it is used. This usage has the following general form:
super. member
Here , member can be either a method or an instance variable.
This second form of super is most applicable to situation in which member names of a subclass
hide members by the same name in the super class. Consider this simple class hierarchy :
// Using super to overcome name hiding
class A { }
int i void show ( ) {
} System.out.println ( “ i in superclass : “ +
// Create a subclass by extending class A super.i );
class B extends A { System.out.println ( “i in subclass :“ + i );
int i; // this i hides the i in A }}
B ( int a , int b ) class UseSuper {
Super .i = a ; // i in A public static void main ( String args[ ] ) {
i = b ; // i in B B subOb = new B ( 1 , 2 );
SubOb.show( ); }}
This program displays the following :
i in superclass : 1
i in subclass : 2
Although the instance variable i in B hides the i in A, super allows access to the i defined in the
super class. Super can also be used to call methods that are hidden by a subclass.
When Constructors are called
For example, given a subclass called B and a super class called A, is A’s constructor called
before B’s, or vice versa? The answer is that in a class hierarchy, constructors are called in order
of derivation, from super class to subclass. Further, since super( ) must be the first statement
executed in a subclass’ constructor , this order is the same whether or not super ( ) is used. If
super ( ) is not used, then the default or parameter less constructor of each super class will be
executed. The following program illustrates when constructors are executed.
// Demonstrate when constructors are called
// Create a super class
class A { // Create another subclass by extending B
A( ) { class C extends B {
System.out.println ( “ Inside A’s C(){
Constructor . “ ); System.out.println ( “ Inside C’s constructor
}} “);
// Create a subclass by extending class A }}
class B extends A { class CallingCons {
B(){ public static void main ( String args[ ] ) {
System.out.println ( “ Inside B’s constructor. C c = new C ( );
“); }}
}}
The output from this program is shown here :
Inside A’s constructor.
Inside B’s constructor.
Inside C’s constructor.
As you can see, the constructors are called in order of derivation.
If you think about it, it makes sense that constructor functions are executed in order of
derivation. Because a super class has no knowledge of any subclass, any initialization it needs to
perform is separate from and possibly prerequisite to any initialization performed by the
subclass. Therefore, it must be executed first.
4.3 Method Overriding
In a class hierarchy, when a method in a subclass has the same and type signature as a method in
its super class, then the method in the subclass is said to override the method in the super class.
When an overridden method is called from within a subclass, it will always refer to the version
of that method defined by the subclass. The version of the method defined by the super class will
be hidden. Consider the following :
// Method overriding
class A { B ( int a, int b, int c) {
int i ,j; super( a, b);
A ( int a, int b) { k= c;
i= a; }
j= b; // display k – this overrides show( ) in A
} void show ( ) {
// display i and j System.out.println ( “ k : “ + k );
void show ( ) { }}
Sytem.out.println ( “ i and j : “ + I + “ “ + class override {
j ); public static void main ( String args[ ] ) {
}} B subob = new B ( 1, 2, 3);
class B extends A { subob.show( ) ; // this calls show( ) in B;
int k; }}
The output produced by this program is shown here:
k:3
When show( ) is invoked on an object of type B, the version of show ( ) defined within B is used.
That is, the version of show ( ) inside B overrides the version declared in A.
If you wish to access the super class version of an overridden function, you can do so by using
super. For example, in this version of B, the super class version of show( ) is invoked within the
subclass version. This allows all instance variables to be displayed.
Simple example
public class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal");
}
}
class B extends A {
int k;
B ( int a, int b ,int c) {
super ( a,b);
k = c;
}
void show ( ) {
super.show( ) ; // this calls A’s show( )
System.out.println ( “ k : “ + k) ;
}}
If you substitute this version of A into the previous program, you will see the following output :
i and j : 1 2
k:3
Here, super.show() calls the superclass version of show ( ).
Method overriding occurs only when the names and the type signatures of the two methods are
identical. If they are not, then the two methods are simply overloaded. For example, consider this
modified version of the preceding example :
// Methods with differing type signatures are overloaded – not overridden
class A {
int i , j;
A ( int a, int b ) {
i = a;
j = b;
}
// display i and j
void show() {
System.out.println ( “ i and j : “ + i + “ “ + j );
}}
// Create a subclass by extending class A.
class B extends A {
int k;
B ( int a, int b, int c ) {
super ( a, b );
k = c;
}
// Overload show ( )
void show ( String msg ) {
System.out.println ( msg + k );
}}
class override {
public static void main ( String args[ ] ) {
B subob = new B ( 1, 2, 3);
Subob.show( “ This is k : “ ) ;
// this calls show() in B
Subob.show( ); // this calls
show( ) in A
}}
The output produced by this program is shown here:
This is k : 3
i and j : 1 2
The version of show( ) in B takes a string parameter. This makes its signature different from the
one in A, which takes no parameters. Therefore, no overriding takes place.