Inheritance
Inheritance Basics
Inheritance can be defined as the process where one object acquires the properties of another. With the use of inheritance the information is made manageable in a hierarchical order. It is one of the cornerstones of Object-oriented programming.
Object-oriented programming allows classes to inherit commonly used state and behaviour from other classes. For example, consider the staffs of a college. Staff is a generalised term. It contains teachers and non-teaching staff. Teachers in turn contain lectures, tutors, professors etc. But there are some properties which are common to all. Teachers may have additional features like subject. Non teaching staff may have features showing the nature of their work. So staff can be thought of as a class having the common features like name, address etc. Teachers can be another class inheriting these features and add additional features like subject. Non-teaching staff can also inherit features of staff adding its own features to that. A pictorial representation is shown below
In short inheritance is a powerful tool that allows us to make our programs resemble the real world.
The most important advantage of inheritance is reusability. As a class can inherit the properties of another class, a programmer need not write the same code again. Also inheriting properties from classes that are well tested reduces the testing effort of the newly developed class.
Inheritance can be broadly classified as:
· Single inheritance
· Multiple inheritance
· Hierarchical inheritance
· Multilevel inheritance and
· Hybrid inheritance which is a combination of two or more of the above types.
Following figure represents these:
Java does not support multiple inheritance directly.
Inheritance in Java
In Java the class that is inherited is known as superclass (also called parent class/base class) and the class that does inheriting is known as subclass (also called child class/derived class). Subclasses inherit all the fields and methods that are defined in the superclass as well as adds its own. Inheritance relation of classes is shown using the keyword extends. The syntax is:
Class subclass_name extends superclass_name{
// fields of subclass
// methods of subclass
}
Now Let us consider an example. Class Rectangle has two fields length and breadth. Class Box inherits Rectangle adding its own field height.
class Rectangle{
int length, breadth;
}
class Box extends Rectangle{
int height;
}
class InheritanceTest{
public static void main(String[] args){
Box b1 = new Box();
b1.length = 10;
b1.breadth = 5;
b1.height = 6;
System.out.println(“Length = ”b1.length);
System.out.println(“Breadth = ”b1.breadth);
System.out.println(“Height = ”b1.height);
}
}
Output
Length = 10
Breadth = 5
Height = 6
As we can see b1 is an object of Box. Even though length and breadth are not fields of Box, it can perfectly access them as if they were part of Box. Similarly methods that are defined as part of rectangle can also be accessed by b1 as it accesses its own methods. (Access specifiers can be used to restrict access. This is discussed later)
Using super
Adding constructors to the above example we get
class Rectangle{
int length, breadth;
Rectangle(){
length =0;
breadth = 0;
}
Rectangle(int x, int y){
length = x;
breadth = y;
}
}
class Box extends Rectangle{
int height;
Box(){
height = 0;
}
Box(int h){
height = h;
}
}
In this case we have parameterised constructors in both the classes. When we create an object of Box in main, we naturally would like to initialize length, breadth and height. Here length and breadth are initialized in super class Rectangle. So we need some mechanism to call this constructor passing the required values to it from the constructor of Box class. super() can be used for this. It calls the constructor of the immediate super class. So the above program can be modified as:
class Rectangle{
int length, breadth;
Rectangle(){
length =0;
breadth = 0;
}
Rectangle(int x, int y){
length = x;
breadth = y;
}
}
class Box extends Rectangle{
int height;
Box(){
height = 0;
}
Box(int l, int b, int h){
super(l, b);
height = h;
}
}
class superTest{
public static void main(String[] args){
Box b2 = new Box(10,5,6); // length: 10, breadth: 5, height:6
System.out.println(“Length = ”+b2. Length);
System.out.println(“Breadth = ”+b2. Breadth);
System.out.println(“Height = ”+b2. Height);
}
}
Multilevel Hierarchy
As we have seen in the previous section, the super() call inside the subclass calls the constructor of the immediate super class. The code below describes a multilevel inheritance.
class Rectangle{
int length, breadth;
Rectangle(){
length = breadth = 0;
System.out.println(“Inside Rectangle Default”);
}
Rectangle(int x, int y){
length = x;
breadth = y;
System.out.println(“Inside Rectangle”);
}
}
class Box extends Rectangle{
int height;
Box(){
height = 0;
System.out.println(“Inside Box
Default”);
}
Box(int l, int b, int h){
super(l, b); // Calls the constructor Rectangle(l,
b)
height = h;
System.out.println(“Inside Box”);
}
}
class Packet extends Box{
int weight;
Packet(){
weight = 0;
System.out.println(“Inside Packet
Default”);
}
Packet(int l, int b, int h, int w){
super(l, b, h); // Calls the
constructor Box(l, b, h)
weight w;
System.out.println(“Inside Packet”);
}
}
Class Packet extends Box which extends
Rectangle. The constructors are called in the order from the topmost class to
the lowermost in the inheritance hierarchy. So in the above example the
constructor of Rectangle is called first, followed by that of Box and Packet at
last.
The output of the program when an object of
Packet is instantiated is
class
MultilevelHierarchy{
public static void main(String[] args){
Packet p0 = new
Packet(10,5,6,4); // length: 10,
breadth: 5, height:6, weight:4
Packet p1 = new
Packet();
}
}
Output
Inside Rectangle
Inside Box
Inside
Package
Inside Rectangle Default
Inside Box Default
Inside Package Default
There is no need of explicitly calling
default constructors using super(). When super() is not called inside a constructor
java adds a call to the default constructor of the immediate super class. The
last three lines of the output clarify this. The statement Packet p1 = new
Packet(); calls the default constructor of Packet. In side this there is no
call to super(). So java adds this call, which calls the default constructor of
Box. Here again java adds a call to the default constructor of Rectangle, as we
have not added any super() call inside it.
Note: if a super() call is omitted inside a
parameterised constructor, then also java adds a call to the default
constructor of the immediate super class
Abstract and final classes
There are situations in which you will want to
create a superclass that only defines a generalized form that will be shared by
all of its subclasses, leaving it to each subclass to fill in the details. Such
a class determines the nature of the methods that the subclasses must
implement. One way this situation can occur is when a superclass is unable to
create a meaningful implementation for a method.
In many cases, we want some way to ensure that a
subclass does, indeed, override all necessary methods. Java’s solution to this
problem is the abstract method.
We can require that certain methods be overridden by subclasses by
specifying the abstract type modifier. These methods are sometimes
referred to as subclasser responsibility because they have no
implementation specified in the superclass. Thus, a subclass must override
them—it cannot simply use the version defined in the superclass.
To declare an abstract method, use this general
form:
abstract type
name(parameter-list);
Any class that contains one or more abstract methods must also be
declared abstract. To declare a class abstract, you simply use the abstract keyword
in front of the class keyword at the beginning of the class declaration. There can be no objects of an abstract class. That is,
an abstract class cannot be directly instantiated with the new operator. Also,
you cannot declare abstract constructors, or abstract static methods. Any
subclass of an abstract class must either implement all of the abstract methods
in the superclass, or be itself declared abstract.
The Object class
There
is one special class, Object, defined by Java. Every class in the
Java system is a descendent (direct or indirect) of the
Object class. This means that a reference variable of type Object
can refer to an object of any other class. Also, since arrays are
implemented as classes, a variable of type Object can also refer to any
array.
Object defines the following methods:
Method
|
Purpose
|
Object clone( )
|
Creates a new object that is the same as the object being cloned.
|
boolean equals(Object object)
|
Determines whether
one object is equal to another.
|
void finalize( )
|
Called before an unused object is recycled.
|
Class getClass( )
|
Obtains the class
of an object at run time.
|
int hashCode( )
|
Returns the hash code associated with the invoking object.
|
void notify( )
|
Resumes execution
of a thread waiting on the invoking object.
|
void notifyAll( )
|
Resumes execution of all threads waiting on the invoking object
|
String toString( )
|
Returns a string
that describes the object.
|
void wait( )
void wait(long milliseconds)
void wait(long milliseconds, int
nanoseconds)
|
Waits on another thread of execution.
|
Note: The methods getClass( ), notify( ),
notifyAll( ), and wait( ) are declared as final. The
details of them are available in the section Threading.
The toString(
) method returns a string that contains a description of the object on
which it is called. Also, this method is automatically called when an object is
output using println( ).

No comments:
Post a Comment