Inheritance Concepts In Java

Inheritance

  • One of OOPs’ strength is Inheritance. Inheritance allows the creation of hierarchical classifications’ of classes.
  • Inheritance means, one can create a general class that defines certain properties common to a set of related items, and then this class can be inherited by other classes, each adding those properties.
  • Super Class :In java, a class that is inherited is called super class.
  • Sub Class : In java, the class that does the inheriting is called a subclass. In other words, a sub class is a specialized version of a super class. It inherits all of the permitted instance variables and permitted member methods, defined by the super class and adds its own, unique elements.
  • The super class also can be used to create an object in main () method, further a subclass can be a super class for another subclass.
  • To inherit a class, simply use extends key word
  • The general form of a class declaration that inherits super class

class subclass-name extends superclass-name

// body of class.

  • Remember:

ü  You can specify only one super class for any subclass.(java does not support multiple class inheritance, into a single sub class, This differs from C++, in which you can inherit multiple base classes, into a single derived class). Thus java does not support multiple inheritance but supports only multi level inheritance.

ü  No class can be a super class of it self.

/*

This program illustrates the power of inheritance. class Box is a super class and the sub classBoxWeight inherits the Box class, by using the extends keyword

*/

class Box

double width,height,depth;

//constructor used when no dimensions specified.

Box()

width = height = depth = -1;

// constructor used when all dimensions specified.

Box(double w, double h, double d)

width = w;height = h;depth = d;

//constructor used when cube is created.

Box(double side)

width = height = depth = side;

// construct clone of an object

Box(Box obj)

width = obj.width;

height = obj.height;

depth = obj.depth;

// compute return volume

double volume ()

return depth * height * depth;

// here, Box is extended to include weight

class BoxWeight extends Box

double weight; // weight of Box

// constructor for BoxWeight class

BoxWeight(double w, double h, double d, double m)

width = w;

height = h;

depth = d;

weight = m;

class BoxWeightDemo

public static void main(String args[])

BoxWeight MyBox1 = new BoxWeight(23.33,33.33,43.33,50);

BoxWeight MyBox2 = new BoxWeight(33.33,43.33,53.33,150);

double vol = MyBox1.volume();

System.out.println(“volume of MyBox1 is  : “+vol);

System.out.println(“weight of MyBox1 is  : “+MyBox1.weight+” kgs”);

vol = MyBox2.volume();

System.out.println(“volume of MyBox2 is  : “+vol);

System.out.println(“weight of MyBox2 is  : “+MyBox2.weight+” kgs”);

Explanation : A major advantage of inheritance is that once a class is created it can be used, as a super class to create any number of subclasses and each subclass can precisely tailor its own classification. Now consider this example, which again makes use of Box class.

/* A class inherits Box and adds color attribute */

/*  This program illustrates the power of inheritance  */

class Box

double width,height,depth;

//constructor used when no dimensions specified.

Box()

width = height = depth = -1;

// constructor used when all dimensions specified.

Box(double w, double h, double d)

width = w;

height = h;

depth = d;

//constructor used when cube is created.

Box(double side)

width = height = depth = side;

// construct clone of an object

Box(Box obj)

width = obj.width;

height = obj.height;

depth = obj.depth;

// compute return volume

double volume ()

return depth * height * depth;

// here, Box is extended to include color

class BoxColor extends Box

String color; // color of Box

// constructor for BoxColor class

BoxColor(double w, double h, double d, String str)

width =  w;

height = h;

depth =  d;

color =str;

class BoxColorDemo

public static void main(String args[])

BoxColor MyBox1 = new BoxColor(23.33,33.33,43.33,”RED”);

BoxColor MyBox2 = new BoxColor(33.33,43.33,53.33,”BLUE”);

double vol = MyBox1.volume();

System.out.println(“volume of MyBox1 is  : “+vol);

System.out.println(“Color of MyBox1 is  : “+MyBox1.color);

vol = MyBox2.volume();

System.out.println(“volume of MyBox2 is  : “+vol);

System.out.println(“Color of MyBox2 is  : “+MyBox2.color);

Explanation : Compare this subclass ColorBox and BoxWeight. Each subclass adds its own unique attributes. This is the strength of inheritance.

A Superclass Variable Can Reference a Subclass Object

  • A reference variable of a superclass can be assigned a reference to any subclass derived from that superclass.
  • This aspect of inheritance is quite useful in a variety of situations.

/*consider the below example in which a super class variable references a subclass Object.*/

class Box

double WIDTH,LENGTH,HEIGHT;

Box()

WIDTH=LENGTH=HEIGHT=-1;

Box(double side)

WIDTH=LENGTH=HEIGHT=side;

Box(double WIDTH,double LENGTH,double HEIGHT)

this.LENGTH = LENGTH;

this.WIDTH = WIDTH;

this.HEIGHT = HEIGHT;

Box(Box obj)

WIDTH  =  obj.WIDTH;

LENGTH = obj.LENGTH;

HEIGHT = obj.WIDTH;

double volume()

return (LENGTH * WIDTH * HEIGHT);

class BoxWeight extends Box

double WEIGHT;

BoxWeight()

super();

WEIGHT=-1;

BoxWeight(double side,double WEIGHT)

super(side);

this.WEIGHT = WEIGHT;

BoxWeight(double WIDTH,double LENGTH,double HEIGHT,double WEIGHT)

super(WIDTH,LENGTH,HEIGHT);

this.WEIGHT = WEIGHT;

BoxWeight(BoxWeight obj)

super(obj);

this.WEIGHT = obj.WEIGHT;

class RefDemo

public static void main(String args[])

BoxWeight weightbox = new BoxWeight(3,5,7,8.37);

Box       plainbox  = new Box();

System.out.println(“The volume of the box “+weightbox.volume());

System.out.println(“The weight of the box “+weightbox.WEIGHT);

//Now assign BoxWeight reference to Box reference

plainbox = weightbox;

//The following statement is valid because Box defines volume() method

System.out.println(“The volume of the box “+plainbox.volume());

//The following statement is invalid because Box doesnot define WEIGHT member

// System.out.println(“The weight of the box “+plainbox.WEIGHT);

Explanation: It is the type of reference variable, that determines what members can be accessed. when a reference to a subclass object is assigned to a superclass reference variable, we will have access to those parts of the object defined by the superclass. This makes sense, because superclass has no knowledge of what a subclass adds to it.This is why the last code in the above program is illegal and hence is commented.

Member Access and Inheritance

  • Although a subclass includes all of the members of its super class, it cannot access those members of the superclass that have been declared as private.
  • Java provides a solution, for this problem, by using a key word super.

Using Super

  • When u declare member variables of a class using access specifier, private and if you use  that class as super class, then  there would be no way for a subclass to directly access or initialize these variables, on its own(because the primary attribute of OOP’s, encapsulation is implemented).
  • Java provides a solution, for this problem,by using a key word super.
  • Whenever a subclass needs to refer to its super class, it can do so using super.
  • super has two general forms of uses:
  1. The first use is to, call the super class’s constructor.
    1. The second use is to, access a member of the superclass that has been hidden by a member of a subclass. The member could be either a member variable or member method of a class
  • Lets examine the uses of super, here in detail
  1. First use of super :

Using super to call super class constructors.

A subclass can call, a super class constructor method, by use of the following form of super

super( parameter-list )

here parameter-list specifies, parameters needed, if any, by the constructor in the super class.

  • Remember super() must always be the first statement, to be executed in side the subclasses

constructor.

/*

lets reconsider the example BoxWeigthDemo.java and save it as  BoxWeigthDemo1.java.

This program illustrates the power of ecapsulation and usage  of super key word in  the inheritance

process

*/

//   A complete implementation of BoxWeight

/*

This program illustrates the power of inheritance

*/

class Box

private double width;

private double height;

private double depth;

//constructor used when no dimensions specified.

Box()

width = height = depth = -1;

//constructor used when cube is created.

Box(double side)

width = height = depth = side;

// constructor used when all dimensions specified.

Box(double w, double h, double d)

width = w;

height = h;

depth = d;

// construct clone of an object

Box(Box obj)

width = obj.width;

height = obj.height;

depth = obj.depth;

// compute return volume

double volume ()

return depth * height * depth;

// here, Box is extended to include weight

class BoxWeight extends Box

double weight; // weight of Box

// constructor for BoxWeight class with no values initialized

BoxWeight()

super();

weight =-1;

// constructor for BoxWeight class,for creating a cube object

BoxWeight(double len, double m)

super(len);

weight = m;

// constructor for BoxWeight class, accepting four arguments (three of sides and one of weight)

BoxWeight(double w, double h, double d, double m)

super(w,h,d);

weight = m;

// constructor for BoxWeight class

BoxWeight(Box obj, double m)

super(obj);

weight = m;

// Implementation of class BoxWeight class

class BoxWeightDemo1

public static void main(String args[])

BoxWeight MyBox1 = new BoxWeight(23.33,33.33,43.33,50);

BoxWeight MyBox2 = new BoxWeight(33.33,43.33,53.33,150);

BoxWeight MyBox3 = new BoxWeight(MyBox1,150);

double vol = MyBox1.volume();

System.out.println(“volume of MyBox1 is  : “+vol);

System.out.println(“weight of MyBox1 is  : “+MyBox1.weight+” kgs”);

vol = MyBox2.volume();

System.out.println(“volume of MyBox2 is  : “+vol);

System.out.println(“weight of MyBox2 is  : “+MyBox2.weight+” kgs”);

vol = MyBox3.volume();

System.out.println(“volume of MyBox3 is  : “+vol);

System.out.println(“weight of MyBox3 is  : “+MyBox3.weight+” kgs”);

Explanation : super is called with an object of BoxWeight and not of type Box. This still invokes the constructor Box(Box obj).

lets consider another example, now consider BoxColorDemo class again,

// complete implementation of BoxColor

/*  This program illustrates the power of inheritance  */

class Box

private double width,height,depth;

//constructor used when no dimensions specified.

Box()

width = height = depth = -1;

//constructor used when all dimensions specified.

Box(double w, double h, double d)

width = w;

height = h;

depth = d;

//constructor used when cube is created.

Box(double side)

width = height = depth = side;

//construct clone of an object

Box(Box obj)

width = obj.width;

height = obj.height;

depth = obj.depth;

//compute return volume

double volume ()

return depth * height * depth;

// here, Box is extended to include color

class BoxColor extends Box

String color;// color of Box

// constructor for BoxColor, for a cube, class

BoxColor(double len, String str)

super(len);

color = str;

// constructor for BoxColor class

BoxColor(double w, double h, double d, String str)

super(w,h,d);

color =str;

// constructor for BoxColor class accepting object of type class as parameter

BoxColor(Box obj,String str)

super(obj);

color = str;

// implementation of BoxColor

class BoxColorDemo1

public static void main(String args[])

BoxColor MyBox1 = new BoxColor(23.33,33.33,43.33,”RED”);

BoxColor MyBox2 = new BoxColor(33.33,43.33,53.33,”BLUE”);

BoxColor MyBox3 = new BoxColor(MyBox1,”BLUE”);

double vol = MyBox1.volume();

System.out.println(“volume of MyBox1 is  : “+vol);

System.out.println(“Color of MyBox1 is  : “+MyBox1.color);

vol = MyBox2.volume();

System.out.println(“volume of MyBox2 is  : “+vol);

System.out.println(“Color of MyBox2 is  : “+MyBox2.color);

vol = MyBox3.volume();

System.out.println(“volume of MyBox3 is  : “+vol);

System.out.println(“Color of MyBox3 is  : “+MyBox3.color);

Explanation : super is called with an object of BoxColor and not of type Box. This still invokes the constructor Box(Box obj).

  • Remember

ü  When a sub class calls super(), it is calling the constructor of its immediate super class.

ü  super() always refers to the super class immediately above the calling class.

ü  Also, super() must always be the first statement to be executed inside a subclass constructor.

1.1 Lets examine of super in multilevel hierarchy , the below program which reveals the  usage

/*

In this program Box is used as a super class of BoxWeight and (this subclass ) Box weight

is used as a   super class of ShipMent

*/

class Box

private double width;

private double height;

private double depth;

//constructor used when no dimensions specified.

Box()

width = height = depth = -1;

//constructor used when cube is created.

Box(double side)

width = height = depth = side;

// constructor used when all dimensions specified.

Box(double w, double h, double d)

width = w;

height = h;

depth = d;

// construct clone of an object

Box(Box obj)

width = obj.width;

height = obj.height;

depth = obj.depth;

// compute return volume

double volume ()

return depth * height * depth;

// Here, class Box is extended to include weight

class BoxWeight extends Box

double weight; // weight of Box

// constructor used when dimensions are not specified,for BoxWeight class

BoxWeight()

super();

weight = -1;

// construct a cube of BoxWeight class

BoxWeight(double len, double m)

super(len);

weight = m;

// constructor for BoxWeight class,when all dimensions are specified.

BoxWeight(double w, double h, double d, double m)

super(w,h,d);

weight = m;

// construct a clone, for BoxWeight class

BoxWeight(BoxWeight obj)

super(obj);

weight =obj.weight;

// Here, class BoxWeight is extended to include cost

class ShipMent extends BoxWeight

double cost;

//construct when no values are supplied

ShipMent()

super();

cost = -1;

//construct when cube create

ShipMent(double side,double m,double c)

super(side,m);

cost = c;

//construct when all values supplied

ShipMent(double w,double h,double d,double m,double c)

super(w,h,d,m);

cost = c;

//construct clone of object

ShipMent(ShipMent obj)

super(obj);

cost = obj.cost;

class ShipMentDemo

public static void main(String args[])

ShipMent MyBox1 = new ShipMent(23.33,33.33,43.33,50,153.89);

ShipMent MyBox2 = new ShipMent(33.33,150,304.78);

ShipMent MyBox3 = new ShipMent(MyBox1);

double vol = MyBox1.volume();

System.out.println(“volume of MyBox1 is  : “+vol);

System.out.println(“weight of MyBox1 is  : “+MyBox1.weight+” kgs”);

System.out.println(“weight of MyBox1 is  : “+MyBox1.cost+”/-“);

vol = MyBox2.volume();

System.out.println(“volume of MyBox2 is  : “+vol);

System.out.println(“weight of MyBox2 is  : “+MyBox2.weight+” kgs”);

System.out.println(“weight of MyBox2 is  : “+MyBox2.cost+”/-“);

vol = MyBox3.volume();

System.out.println(“volume of MyBox3 is  : “+vol);

System.out.println(“weight of MyBox3 is  : “+MyBox3.weight+” kgs”);

System.out.println(“weight of MyBox3 is  : “+MyBox3.cost+”/-“);

Explanation :

1.2       In which order, are the constructors called?

  • In a class hierarchy, constructors are called in the order of derviation, that is from super class to sub class,
  • Further, since super() must be the first statement, to be executed in a subclass constructor. This order is the same whether of not, super() is used. If super() is not used, then the default (parameter less) for each super class will be executed constructor.

Lets  understand the above said with an example,shown below

/*

A Program demonstrating order of call, of constructors’

*/

class A

int i,j;

A()

System.out.println(“Hi The constructor of A class is called”);

class B extends A

int k,l;

B()

System.out.println(“Hi The constructor of B class is called”);

class C extends B

int m,n;

C()

System.out.println(“Hi The constructor of C class is called”);

C(int x,int y)

m = x;

n = y;

System.out.println(“Hi The constructor of C class is called value of m and n “+m+” “+n);

class OrderOfConsDemo

public static void main(String args[])

C obj1 = new C();

C obj2 = new C(1,2);

Explanation : observe the out put’s of both objects obj1 and obj2.

  1. Second use of super :

To access members of the super class hidden by members of the subclass. The member could

either be a  variable or a method, of a class. The general form is

super.member

2.1 super used to access hidden member variables of a super class

/*          lets best illustrate the usage of super with an example, shown below         */

//usage of super to over come name hidingf

class A

int i;

class B extends A

int i,j; // this hides the i in class A

B(int x,int y)

i = x;

super.i = y;

j = super.i;

void show()

System.out.println(“value of i in class A  “+super.i+”value of j  “+j);

class UseSuper

public static void main(String args[])

B obj = new B(10,20);

System.out.println(“value of i in B class is “+obj.i);

System.out.println(“value of i in A class is “+obj.j);

obj.show();

Let us bring  polymorhism memories again

We had already discussion about polymorphism in session (DetailedLookAtMethodsAndClasses-2). There we had discussed, in length, about one form of polymorphism: method overloading.

In this session we discuss, method overriding in detail.

2.2   Method Over Riding In a class hierarchy when a method in a sub class and super class, has the same name and type signature(parameters), then the method in subclass, is said to over ride, the method in the super class.

  • Remember

ü  When an overridden method is called from with in a subclass.The call will always refer to the version of the method defined by the subclass.The version defined by the super class will always be hidden.

lets understand, with an example shown, below.

/*

Method overriding

*/

// method overriding demo

class A

int i,j;

A(int x,int y)

i = x;

j = y;

void display()

System.out.println(“Display method of class A is called with values of i and j “+i+” “+j);

class B extends A

int k,l;

B(int x,int y)

super(x+10,y+10);

k = x;

l = y;

/* possible to assign values to i and j of class A in constructor of B

i = x + 10;

j = y + 10;

*/

void display()

System.out.println(“Display method of class B is called with values of K and l “+k+” “+l);

class MethodOverRideDemo

public static void main(String args[])

B obj = new B(20,23);

obj.display();//this calls display() method of class B

  • Remember

ü  Over ridden methods allow java to support dynamic, run-time polymorphism.

ü  Method over riding occurs only when name and type signatures of the two methods are identical, If they are not then the methods are simply over loaded.

ü   Polymorphism is essential to object oriented programming for one reason, it allows to specify methods in a general class that will be common to all  of its,subclasss'(derivatives),while allowing the subclasses to define specific implementation of some or all of those methods.

2.2.1 Applying Method Over Loading lets examine the benefits of method over riding with the help of  examples below

/*

This program creates a super class called Figure that stores dimensions of various,two

dimensional objects.It also defines a method called area() that computes the area of an

object.The program derives two subclasses from figure.The first is Rectangle and the second

is Triangle.Each of these subclasses overrides area() so that it returns the area of a

rectangle and a triangle, respectively.

*/

class Figure

double dim1;

double dim2;

Figure(double x,double y)

dim1 = x;

dim2 = y;

double area()

System.out.println(“Area of figure undefined”);

return 0;

class Rectangle extends Figure

Rectangle(double x,double y)

super(x,y);

double area()

return dim1 * dim2;

class Triangle extends Figure

Triangle(double x,double y)

super(x,y);

double area()

return (float)1/2 * dim1 * dim2;

class FindArea

public static void main(String args[])

Figure    fig = new Figure(10,10);

Rectangle rec = new Rectangle(9,5);

Triangle  tri = new Triangle(10,8);

System.out.println(“area of figure is “+ fig.area());

System.out.println(“area of rectangle is “+ rec.area());

System.out.println(“area of triangle is “+ tri.area());

3  Introducing final key word

The key word final has three uses.

ü  First,it can be used to create the equivalent of a named constant.

ü  The other two uses of final apply to inheritance.

Both are examined here

3.1 Using final with variable

  • Declaring a variable , as final, prevents the contents of the variable from being modified.

Syntax:

final type variable-name = value;

For example

final int FILE_OPEN = 1;

final int FILE_CLOSE = 2;

final int FILE_SAVE = 3;

final int FILE_ SAVEAS = 4;

final int FILE_ QUIT = 5;

  • The variable declared as final can be directly used with in the program, FILE_OPEN ,  FILE_NEW,FILE_SAVE etc as if they were constants, with out fear that a value has been changed).
  • Remember

ü  You must initialize a variable declared as final, during declaration only( final is similar to const in c,c++).

ü  It is a coding convention to choose all upper case indentifiers for final variables.

3.2 Using final with inheritance

i) Using final to prevent over riding:

Though method over riding is java’s most powerful feature, there will be times when you will want to prevent it from occurring.To achieve this simply specify final as a modifier at the start of its declaration, consider the code fragment

//fragment of code demonstrating erroneous implementation of over riding

class A

final void meth()

System.out.println(“This is a final method”);

class B extends A

void meth()  //Error can’t over ride cause meth() method is already declared as final in class A

System.out.println(“This method wont be printed”);

/*

This program demonstrates practically that over loaded forms of methods are not

affected by methods declared as final.

*/

class A

final void meth()

System.out.println(“This is the final method”);

class B extends A

void meth()               //Not Ok, Error; cause This meth() is declared final in class A

System.out.println(“illegal and this wont work”);

void meth( int x)//This is ok because over loaded form of meth(int x) is

System.out.println(“u are in B and x = “+x);//not declared final in class A

class UseFinalMethod

public static void main(String args[])

B obj1 = new B();

obj1.meth(2);

Explanation:

  • Remember

ü   Only those methods, with same name and signature parameter , declared as final cannot be over rided but they can be over loaded. as demonstrated in the above example.

ü  If final method tried to be over ridden, compile time error will occur.

ii) Using FINAL to prevent Inheritance

Though Inheritance is java’s most powerful feature, there will be times when you will want a class, to be prevented, from being  inherited. To achieve this simply specify final as a modifier preceding the class declaration.

Thus to prevent a class from being further inherited, follow the general syntax shown below

final class class-name

// statements;

consider the code fragment,

final class A

//statements;

class B extends A // Error ! can’t sub class

//statements;

2.            Abstract Classes

Some times we would want to create a super class that only defines a generalized form , that will be common to all  of its, subclasses ‘(derivatives), leaving it to each sub class to fill in the details.

You may have certain  methods  which must be over ridden by a subclass, so that the sub class will have a meaning. In such a case, there should be some way to ensure that a subclass does, indeed, over ride all necessary methods. Javas’ solution to this problem is the abstract method.

To declare a method abstract use the following general form:

abstract   return-type  method-name(ParameterList);

  • Remember

ü  abstract method,  does not define method body defined.

Any class that contains one or more abstract methods must also be declared abstract. To declare a

class  abstract simply use the abstract key word in front of the class key word at the beginning of

the class declaration as shown below

abstract class class-name

abstract method1(ParameterList);

abstract method2(ParameterList);

//

//

abstract methodN(ParameterList);

Restrictions with Abstract Classes

  • It is illegal to declare a class as both final and abstract, becuase an abstract class is incomplete by it self and relies up on a sub class for implementation.
  • An abstract class cannot be directly instantiated with the new operator because such objects would be useless as an abstract class is not fully defined.
  • An abstract class cannot declare abstract constructors.
  • An abstract class cannot declare static abstract methods.
  • Any subclass of an abstract class must be either implement all of the abstract methods of the super class or be declared it self as abstract.

Lets’ illustrate this with the help of an example.

/*

A simple demonstration of abstract class

*/

abstract class A

abstract void CallMe();

// concrete methods are still allowed in abstract class

void CallMeToo()

System.out.println(“This is a fully defined method in abstract class”);

class B extends A

// since call me is an abstract method ic class A, so it is over ridden below

void CallMe()

System.out.println(“B’s implementation of CallMe which is an abstract” +

“method in class A”);

class AbstractClassDemo

public static void main(String args[])

B Obj1 = new B();

Obj1.CallMe();

Obj1.CallMeToo();

  • Remember

ü  Although abstract classes cannot be used to instantiate objects, they can be used to create object references.

ü   Concrete methods, which define the entire body, are still allowed in abstract class.

Although abstract classes cannot be used to instantiate objects, they can be used to create object references.

As we are aware java’s runtime polymorphism is implemented through the use of super class references.Thus it must be possible to create a reference to an abstract class so that it can be used to point to a subclass object. This is best illustrated with the example below

/*

using abstract method and classes and creating  a reference to an abstract class so that it

can be used to point to a subclass object. This is best illustrated with the example below

*/

abstract class Figure

double dim1,dim2;

Figure(double x,double y)

dim1 = x;

dim2 = y;

abstract double area();

class Rectangle extends Figure

Rectangle(double x,double y)

super(x,y);

double area()

return dim1 * dim2;

class Triangle extends Figure

Triangle(double x,double y)

super(x,y);

double area()

return ((float)1/2)*(dim1*dim2);

class AbstractClassImplementation

public static void main(String args[])

//            Figure f = new Figure(10,10);//Illegal because abstract classes cannot be

//instantiated

Rectangle r = new Rectangle(9,5);

Triangle t = new Triangle(10,8);

Figure figref;//creating instance variable of Figure with null as value stored.

figref = r;

System.out.println(“area of Rectangle is “+ figref.area());

figref = t;

System.out.println(“area of Triangle is “+ figref.area());