1
MODULE 3
Inheritance: Inheritance Basics, Using Super, Creating A Multilevel Hierarchy, When Constructors Are
Executed, Method Overriding, Dynamic Method Dispatch, Using Abstract Classes, Using Final With
Inheritance, Local Variable Type Inference, Inheritance, The Object Class
Interfaces: Interfaces , Default Interface Method , Use Static Method In An Interface ,Private Interface
Method
Inheritance
Inheritance is one of the building blocks of object oriented programming languages. It allows creation of
classes with hierarchical relationship among them. Using inheritance, one 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 superclass. The class that does the inheriting is called a subclass. Therefore, a subclass is a
specialized version of a superclass. It inherits all of the instance variables and methods defined by the
superclass and add its own, unique elements. Through inheritance, one can achieve re-usability of the
code.
In Java, inheritance is achieved using the keyword extends. The syntax is given below:
class A //super class
{
//members of class A
}
class B extends A //sub class
{
//members of B
}
Consider a program to understand the concept:
class A
{
int i, j;
void showij()
{
[Link]("i and j: " + i + " " + j);
}
}
//create a subclass by extending class A
class B extends A
{
int k;
void showk()
{
[Link]("k: " + k);
2
}
voidsum()
{
[Link]("i+j+k: " + (i+j+k));
}
}
class SimpleInheritance
{ public static void main(String args[])
{
A superOb = new A();
B subOb = new B();
superOb.i=10;
superOb.j = 20;
[Link]("Contents of superOb: ");
[Link]();
subOb.i =7;
subOb.j =8;
subOb.k =9;
[Link]("Contents of subOb: ");
[Link]();
[Link]();
[Link]("Sum of i, j and k in subOb:");
[Link]();
}
}
OUTPUT
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
Note that, private members of the super class can not be accessed by the sub class. The subclass contains
all non-private members of the super class and also it contains its own set of members to achieve
specialization.
3
3.19.1 Type of Inheritance
• Single Inheritance: If a class is inherited from one parent class, then it is known as single
inheritance. This will be of the form as shown below –
superclass
subclass
The previous program is an example of single inheritance.
• Multilevel Inheritance: If several classes are inherited one after the other in a hierarchical manner,
it is known as multilevel inheritance, as shown below –
3.19.2 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. Consider the following for illustration:
class Base
{ void dispB()
{
[Link]("Super class " );
}
}
class Derived extends Base
{ void dispD()
{
4
[Link]("Sub class ");
}
}
class Demo
{ public static void main(String args[])
{
Base b = new Base();
Derived d=new Derived();
b=d; //superclass reference is holding subclass object
[Link]();
//[Link](); error!!
}
}
Note that, the type of reference variable decides the members that can be accessed, but not the type
of the actual object. That is, when a reference to a subclass object is assigned to a superclass reference
variable, you will have access only to those parts of the object defined by the superclass.
3.20 Using super
In Java, the keyword super can be used in following situations:
• To invoke superclass constructor within the subclass constructor
• To access superclass member (variable or method) when there is a duplicate member name in the
subclass
Let us discuss each of these situations:
• To invoke superclass constructor within the subclass constructor: Sometimes, we may need
to initialize the members of super class while creating subclass object. Writing such a code in
subclass constructor may lead to redundancy in code. For example,
class Box
{ double w, h, b;
Box(double wd,
double ht,
double br)
{ w=wd; h=ht; b=br;
}
}
class ColourBox extends Box
{ int colour;
ColourBox(double wd, double ht, double br, int c)
{ w=wd; h=ht; b=br; //code redundancy colour=c;
}
}
5
Also, if the data members of super class are private, then we can’t even write such a code in subclass
constructor. If we use super() to call superclass constructor, then it must be the first statement
executed inside a subclass constructor as shown below –
class Box
{ double w, h, b;
Box(double wd, double ht, double br)
{ w=wd; h=ht; b=br;
}
}
class ColourBox extends Box
{ int colour;
ColourBox(double wd, double ht, double br, int c)
{ super(wd, ht, br); //calls superclass constructor colour=c;
}
}
class Demo
{ public static void main(String args[])
{
ColourBox b=new ColourBox(2,3,4, 5);
}
}
Here, we are creating the object b of the subclass ColourBox . So, the constructor of this class is invoked.
As the first statement within it is super(wd, ht, br), the constructor of superclass Box is invoked, and
then the rest of the statements in subclass constructor ColourBox are executed.
• To access superclass member variable when there is a duplicate variable name in the
subclass: This form of super is most applicable to situations in which member names of a subclass
hide members by the same name in the superclass.
class A
{ int a;
}
class B extends A
{ int a; //duplicate variable a
B(int x, int y)
{
super.a=x; //accessing superclass a
6
a=y; //accessing own member a
}
void disp()
{
[Link]("super class a: "+ super.a);
[Link]("sub class a: "+ a);
}
}
class SuperDemo
{ public static void main(String args[])
{
B ob=new B(2,3); [Link]();
}
}
super class a:2
sub class a:3
3.21 Creating Multilevel Hierarchy
Java supports multi-level inheritance. A sub class can access all the non-private members of all of its super
classes. Consider an illustration:
class A
{ int a;
}
class B extends A
{ int b;
}
class C extends B { int
c;
C(int x, int y, int z)
{ a=x; b=y; c=z;
} void
disp()
{
[Link]("a= "+a+ " b= "+b+" c="+c);
}
}
class MultiLevel
{ public static void main(String args[])
{
7
C ob=new C(2,3,4);
[Link]();
}
}
3.22 When Constructors are called
When class hierarchy is created (multilevel inheritance), the constructors are called in the order of their
derivation. That is, the top most super class constructor is called first, and then its immediate sub class
and so on. If super is not used in the sub class constructors, then the default constructor of super class
will be called.
class A
{
A()
{
[Link]("A's constructor.");
}
}
class B extends A
{
B()
{
[Link]("B's constructor.");
}
}
class C extends B
{
C()
{
[Link]("C's constructor.");
}
} class
CallingCons
{ public static void main(String
args[])
{
C c = new C();
}
}
Output:
A's constructor
B's constructor
C's constructor
8
3.23 Method Overriding
In a class hierarchy, when a method in a subclass has the same name and type signature as a method in
its superclass, then the method in the subclass is said to override the method in the superclass. 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 superclass will be hidden.
class A
{ int i, j;
A(int a, int b)
{ i = a; j =
b;
} void show() //suppressed
{
[Link]("i and j: " + i + " " + j);
}
}
class B extends A
{ int k;
B(int a, int b, int c)
{ super(a, b); k =
c;
} void show() //Overridden method
{
[Link]("k: " + k);
}
}
class Override
{ public static void main(String args[])
{
B subOb = new B(1, 2, 3);
[Link]();
}
}
Output:
k: 3
Note that, above program, only subclass method show() got called and hence only k got displayed. That
is, the show() method of super class is suppressed. If we want superclass method also to be called, we
can re-write the show() method in subclass as –
void show()
{ [Link](); // this calls A's show()
[Link]("k: " + k);
}
9
Method overriding occurs only when the names and the type signatures of the two methods (one in
superclass and the other in subclass) are identical. If two methods (one in superclass and the other in
subclass) have same name, but different signature, then the two methods are simply overloaded.
3.24 Dynamic Method Dispatch
Method overriding forms the basis for one of Java’s most powerful concepts: dynamic method dispatch.
Dynamic method dispatch is the mechanism by which a call to an overridden method is resolved at run time, rather
than compile time. Java implements run-time polymorphism using dynamic method dispatch. We know
that, a superclass reference variable can refer to subclass object. Using this fact, Java resolves the calls
to overridden methods during runtime. When an overridden method is called through a superclass
reference, Java determines which version of that method to execute based upon the type of the object
being referred to at the time the call occurs. Thus, this determination is made at run time. When different
types of objects are referred to, different versions of an overridden method will be called. In other words, it
is the type of the object being referred to (not the type of the reference variable) that determines which
version of an overridden method will be executed. Therefore, if a superclass contains a method that is
overridden by a subclass, then when different types of objects are referred to through a superclass
reference variable, different versions of the method are executed.
class A
{ void callme()
{
[Link]("Inside A");
}
}
class B extends A
{ void callme()
{
[Link]("Inside B");
}
}
class C extends A
{ void callme()
{
[Link]("Inside C");
}
}
class Dispatch
{ public static void main(String args[])
{
A a = new A();
B b = new B();
C c = new C();
10
A r; //Superclass reference
r = a; //r refers to an A Object
[Link]();
r = b;
[Link](); r
= c;
[Link]();
}
}
Inside A
Inside B
Inside C
Why overridden methods?
Overridden methods are the way that Java implements the “one interface, multiple methods” aspect of
polymorphism. superclasses and subclasses form a hierarchy which moves from lesser to greater
specialization. Used correctly, the superclass provides all elements that a subclass can use directly. It also
defines those methods that the derived class must implement on its own. This allows the subclass the
flexibility to define its own methods, yet still enforces a consistent interface. Thus, by combining inheritance
with overridden methods, a superclass can define the general form of the methods that will be used by all
of its subclasses. Dynamic, run-time polymorphism is one of the most powerful mechanisms that
objectoriented design brings to bear on code reuse and robustness.
3.25 Using Abstract Classes
Sometimes, the method definition will not be having any meaning in superclass. Only the subclass
(specialization) may give proper meaning for such [Link] such a situation, having a definition for a
method in superclass is absurd. Also, we should enforce the subclass to override such a method. A method
which does not contain any definition in the superclass is termed as abstract method. Such a method
declaration should be preceded by the keyword abstract. These methods are sometimes referred to as
subclasser responsibility because they have no implementation specified in the superclass.
A class containing at least one abstract method is called as abstract class. Abstract classes can not be
instantiated, that is one cannot create an object of abstract class. Whereas, a reference can be created for
an abstract class.
abstract class A
{ abstract void callme();
void callmetoo()
{
[Link]("This is a concrete method.");
}
}
class B extends A
{ void callme() //overriding abstract method
{
[Link]("B's implementation of callme.");
}
11
class AbstractDemo
{ public static void main(String args[])
{
B b = new B(); //subclass object
[Link](); //calling abstract method
[Link](); //calling concrete method }
}
Example: Write an abstract class shape, which has an abstract method area(). Derive three classes
Triangle, Rectangle and Circle from the shape class and to override area(). Implement run-time
polymorphism by creating array of references to supeclass. Compute area of different shapes and display
the same.
Solution:
abstract class Shape
{
final double PI= 3.1416;
abstract double area();
}
class Triangle extends Shape
{ int b, h;
Triangle(int x, int y) //constructor
{
b=x;
h=y;
}
double area() //method overriding
{
[Link]("\nArea of Triangle is:");
return 0.5*b*h;
}
}
class Circle extends Shape
{ int r;
12
Circle(int rad) //constructor
{ r=rad;
}
double area() //overriding
{
[Link]("\nArea of Circle is:");
return PI*r*r;
}
}
class Rectangle extends Shape
{ int a, b;
Rectangle(int x, int y) //constructor
{ a=x;
b=y;
}
double area() //overriding
{
[Link]("\nArea of Rectangle is:");
return a*b;
}
}
class AbstractDemo
{ public static void main(String args[])
{
Shape r[]={new Triangle(3,4), new Rectangle(5,6),new Circle(2)};
for(int i=0;i<3;i++)
[Link](r[i].area());
}
}
Output:
Area of Triangle is:6.0
Area of Rectangle is:30.0
Area of Circle is:12.5664
Note that, here we have created array r, which is reference to Shape class. But, every element in r is holding
objects of different subclasses. That is, r[0] holds Triangle class object, r[1] holds Rectangle class object
and so on. With the help of array initialization, we are achieving this, and also, we are calling respective
constructors. Later, we use a for-loop to invoke the method area() defined in each of these classes.
3.26 Using final
The keyword final can be used in three situations in Java:
• To create the equivalent of a named constant.
13
• To prevent method overriding
• To prevent Inheritance
To create the equivalent of a named constant: A variable can be declared as final. Doing so prevents
its contents from being modified. This means that you must initialize a final variable when it is declared.
For example:
final int FILE_NEW = 1; final
int FILE_OPEN = 2; final int
FILE_SAVE = 3; final int
FILE_SAVEAS = 4; final int
FILE_QUIT = 5;
It is a common coding convention to choose all uppercase identifiers for final variables. Variables declared
as final do not occupy memory on a per-instance basis. Thus, a final variable is essentially a constant.
To prevent method overriding: Sometimes, we do not want a superclass method to be overridden in the
subclass. Instead, the same superclass method definition has to be used by every subclass. In such
situation, we can prefix a method with the keyword final as shown below –
class A
{ final void meth()
{
[Link]("This is a final method.");
}
}
class B extends A
{ void meth() // ERROR! Can't override.
{
[Link]("Illegal!"); }
}
To prevent Inheritance: As we have discussed earlier, the subclass is treated as a specialized class and
superclass is most generalized class. During multi-level inheritance, the bottom most class will be with all
the features of real-time and hence it should not be inherited further. In such situations, we can prevent a
particular class from inheriting further, using the keyword final. For example –
final class A
{
// ... }
class B extends A // ERROR! Can't subclass A
{
// ... }
Note:
• Declaring a class as final implicitly declares all of its methods as final, too.
• It is illegal to declare a class as both abstract and final since an abstract class is incomplete by itself
and relies upon its subclasses to provide complete implementations
14
3.27 The Object Class
There is one special class, Object, defined by Java. All other classes are subclasses of Object. That is,
Object is a superclass of all other classes. 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, which means that they are available in every
object.
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 Waits on another thread of execution.
milliseconds) void wait(long
milliseconds, int
nanoseconds)
The methods getClass( ), notify( ), notifyAll( ), and wait( ) are declared as final. You may override
the others. The equals( ) method compares the contents of two objects. It returns true if the objects
are equivalent, and false otherwise. The precise definition of equality can vary, depending on the type
of objects being compared. 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( ). Many classes override this method.
15
Interfaces
Interface is an abstract type that can contain only the declarations of methods and constants. Interfaces
are syntactically similar to classes, but they do not contain instance variables, and their methods are
declared without any body. Any number of classes can implement an interface. One class may implement
many interfaces. By providing the interface keyword, Java allows you to fully utilize the “one interface,
multiple methods” aspect of polymorphism. Interfaces are alternative means for multiple inheritance in
Java.
4.2.1 Defining an Interface
An interface is defined much like a class. This is the general form of an interface:
access interface name
{ type final-varname1 = value;
type final-varname2 = value;
return-type method-name1(parameter-list);
return-type method-name2(parameter-list);
…………………
}
Few key-points about interface:
• When no access specifier is mentioned for an interface, then it is treated as default and the interface
is only available to other members of the package in which it is declared. When an interface is
declared as public, the interface can be used by any other code.
• All the methods declared are abstract methods and hence are not defined inside interface. But, a
class implementing an interface should define all the methods declared inside the interface.
• Variables declared inside of interface are implicitly final and static, meaning they cannot be
changed by the implementing class.
• All the variables declared inside the interface must be initialized.
• All methods and variables are implicitly public.
4.2.2 Implementing Interface
To implement an interface, include the implements clause in a class definition, and then create the
methods defined by the interface. The general form of a class that includes the implements clause looks
like this:
class classname extends superclass implements interface1, interface2...
{
// class-body
}
Consider the following example:
16
interface ICallback
{ void callback(int param);
}
class Client implements ICallback
{ public void callback(int p) //note public
{
[Link]("callback called with " + p);
}
voidtest()
{
[Link](“ordinary method”); }
}
class TestIface
{ public static void main(String args[])
{
ICallback c = new Client();
[Link](42);
// [Link]() //error!!
}
}
Here, the interface ICallback contains declaration of one method callback(). The class Client implementing
this interface is defining the method declared in interface. Note that, the method callback() is public by
default inside the interface. But, the keyword public must be used while defining it inside the class. Also,
the class has its own method test(). In the main() method, we are creating a reference of interface pointing
to object of Client class. Through this reference, we can call interface method, but not method of the class.
Accessing Implementations Through Interface References
The true polymorphic nature of interfaces can be found from the following example –
• You can declare variables as object references that use an interface rather than a class type.
• Any instance of any class that implements the declared interface can be referred to by such a
variable.
17
class TestIface {
public static void main(String args[]) {
Callback c = new Client();
[Link](42); }
}
Ouput:
callback called with 42
EX:2
class AnotherClient implements Callback {
public void callback(int p) {
[Link]("Another version of callback"); [Link]("p squared is " + (p*p)); }
}
class TestIface2 {
public static void main(String args[]) {
Callback c = new Client();
AnotherClient ob = new AnotherClient();
[Link](42);
c = ob;
[Link](42);
}
}
Output:
callback called with 42
Another version of callback
p squared is 1764
Note: Interfaces may look similar to abstract classes. But, there are lot of differences between them as
shown in the following table:
Abstract Class Interface
Can have instance methods that implements Are implicitly abstract and cannot have
a default behavior. implementations.
May contain non-final variables. Variables declared in interface are by
default final.
18
Can have the members with private, Members of a Java interface are public by
protected, etc.. default.
A Java abstract class should be extended Java interface should be implemented using
using keyword “extends”. keyword “implements”
An abstract class can extend another Java An interface can extend another Java
class and implement multiple Java interfaces. interface only.
Not slow Compared to abstract classes, interfaces
are slow as it requires extra indirection.
4.2.4 Interfaces can be extended
One interface can inherit another interface by using the keyword extends. The syntax is the same as for
inheriting classes. When a class implements an interface that inherits another interface, it must provide
implementations for all methods defined within the interface inheritance chain.
interface A
{ void meth1();
void meth2();
}
interface B extends A
{ void meth3();
}
class MyClass implements B
{ public void meth1()
{
[Link]("Implement meth1()."); }
public void meth2()
{
[Link]("Implement meth2().");
} public void
meth3()
{
[Link]("Implement meth3().");
}
}
19
class IFExtend
{ public static void main(String arg[])
{
MyClass ob = new MyClass();
ob.meth1(); ob.meth2();
ob.meth3();
}
}
Default Interface Methods
As we are aware that till JDK 7 we couldn’t include implemented method inside an interface. In
other words, there was no provision to have a method body inside a method of an Interface.
Using default method one can include an implemented method inside an Interface. Therefore, we
can also have an implemented method inside an interface.
Beautiful Veneer Lamp 00:19/03:27
Default Method in Interface
If we have an implemented method inside an interface with default keyword, then we will call it as
a Default method. We also call it defender method or virtual extension method. The default
method in interface was introduced in JDK 8
Important Note on Default Methods
▪ We can have Default methods (method with default keyword) only inside Interfaces as of Java 8.
They are not allowed inside classes, even if it is implemented class of that Interface.
▪ Any method inside an Interface can’t be declared default & static together. Default methods can’t
be static & static methods can’t be default.
20
▪ Similar to regular methods, default method in interface is also public implicitly. Hence, we don’t
need to specify the public modifier.
▪ Unlike regular interface methods, default method in interface has its implementation (method
body).
▪ We can have any number of default method in an Interface.
Static method in Interfaces
Static Methods in Interface are those methods, which are defined in the interface with the
keyword static. Unlike other methods in Interface, these static methods contain the
complete definition of the function and since the definition is complete and the method is
static, therefore these methods cannot be overridden or changed in the implementation
class.
Similar to Default Method in Interface, the static method in an interface can be defined in
the interface, but cannot be overridden in Implementation Classes. To use a static
method, Interface name should be instantiated with it, as it is a part of the Interface only.
Output: drawing rectangle
27
21
Private Interface Methods
In Java 9, we can create private methods inside an interface. Interface allows us to declare private
methods that help to share common code between non-abstract method
Question Bank:
1. What is inheritance? Discuss different types of inheritance with suitable example.
2. Discuss the behavior of constructors when there is a multilevel inheritance. Give appropriate code
to illustrate the process.
3. Mention and explain the uses of super keyword in Java.
4. How do you pass arguments to superclass constructor through the subclass constructor? Explain
with a code snippet.
5. Discuss usage of final keyword in Java. Give suitable examples.
6. What do you mean by method overriding? Discuss with a programming example.
7. Explain abstract class and abstract method with suitable code snippet.
8. Write a note on:
a. Finalize() method
b. Object Class
c. Dynamic Method Dispatch
9. Create an abstract class called Employee. Include the members: Name, EmpID and an abstract
method cal_sal(). Create two inherited classes SoftwareEng (with the members basic and DA) and
22
HardwareEng (with members basic and TA). Implement runtime polymorphism (dynamic method
dispatch) to display salary of different employees by creating array of references to superclass.
10. Differentiate method overloading and method overriding.
11. Explain interface in java
12. Explain static and default method in interface