java notes, object oriented programming using java, java tutorial, lecture notes, java programming notes, java example programs, java programs with explanation, java source code with output, java programs, java coding, java codes, java slides, java notes,inheritance in java, java inheritancenotes, java inheritancet notes,different types of inheritance in Java,inheritance with an example, inheritance hierarchy in Java
Class notes(week 6) on inheritance and multiple inheritance
1. Page 1 of 30
Class Notes on Inheritance and Multiple Inheritance (Interfaces)
(Week - 6)
Contents: - Super class & subclasses including multilevel hierarchy, process of constructor calling in inheritance, use of
super and final keywords with super() method, dynamic method dispatch, use of abstract classes, &methods, interfaces.
Inheritance
Inheritance allows the creation of hierarchical classifications in object-oriented programming. 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 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 adds its own, unique
elements.
Definitions: A class that is derived from another class is called a subclass (also a derived class, extended class, or child
class). The class from which the subclass is derived is called a superclass (also a base class or a parent class).
Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). In
the absence of any other explicit superclass, every class is implicitly a subclass of Object.
Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and
ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the
inheritance chain stretching back to Object.
The idea of inheritance is simple but powerful: When you want to create a new class and there is already a class that
includes some of the code that you want, you can derive your new class from the existing class. In doing this, you can
reuse the fields and methods of the existing class without having to write (and debug!) them yourself.
A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not
members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the
subclass.
Java Inheritance defines an is-a relationship between a superclass and its subclasses. This means that an object of a
subclass can be used wherever an object of the superclass can be used. Class Inheritance in java mechanism is used to
build new classes from existing classes.
For example a car class can inherit some properties from a General vehicle class. Here we find that the base class is the
vehicle class and the subclass is the more specific car class. A subclass must use the extends clause to derive from a
super class which must be written in the header of the subclass definition. The subclass inherits members of the
superclass and hence promotes code reuse. The subclass itself can add its own new behavior and properties. The
java.lang.Object class is always at the top of any Class inheritance hierarchy.
Consider the following example:-
2. Page 2 of 30
class Box {
double width;
double height;
double depth;
Box() {
}
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
void getVolume() {
System.out.println("Volume is : " + width * height * depth);
}
}
public class MatchBox extends Box {
double weight;
MatchBox() {
}
MatchBox(double w, double h, double d, double m) {
width = w;
height = h;
depth = d;
weight = m;
}
public static void main(String args[]) {
MatchBox mb1 = new MatchBox(10, 10, 10, 10);
mb1.getVolume();
System.out.println("width of MatchBox 1 is " + mb1.width);
System.out.println("height of MatchBox 1 is " + mb1.height);
System.out.println("depth of MatchBox 1 is " + mb1.depth);
System.out.println("weight of MatchBox 1 is " + mb1.weight);
}
}
Output:-
Volume is : 1000.0
width of MatchBox 1 is 10.0
height of MatchBox 1 is 10.0
depth of MatchBox 1 is 10.0
weight of MatchBox 1 is 10.0
What is not possible using java class Inheritance?
1. Private members of the superclass are not inherited by the subclass and can only be indirectly accessed.
2. Members that have default accessibility in the superclass are also not inherited by subclasses in other packages, as
these members are only accessible by their simple names in subclasses within the same package as the superclass.
3. Since constructors and initializer blocks are not members of a class, they are not inherited by a subclass.
4. A subclass can extend only one superclass
this and super keywords
3. Page 3 of 30
The two keywords, this and super to help you explicitly name the field or method that you want. Using this and super
you have full control on whether to call a method or field present in the same class or to call from the immediate
superclass. This keyword is used as a reference to the current object which is an instance of the current class. The
keyword super also references the current object, but as an instance of the current class’s super class.
The this reference to the current object is useful in situations where a local variable hides, or shadows, a field with the
same name. If a method needs to pass the current object to another method, it can do so using the this reference. Note
that the this reference cannot be used in a static context, as static code is not executed in the context of any object.
class Counter {
int i = 0;
Counter increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
}
public class CounterDemo extends Counter {
public static void main(String[] args) {
Counter x = new Counter();
x.increment().increment().increment().print();
}
}
Output
i=3
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. You will
find this aspect of inheritance quite useful in a variety of situations. For example, consider the following:-
class Box {
double width;
double height;
double depth;
// construct clone of an object
Box(Box ob) { // pass object to constructor
width = ob.width;
height = ob.height;
depth = ob.depth;
}
// constructor used when all dimensions specified
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
4. Page 4 of 30
// constructor used when no dimensions specified
Box() {
width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}
// constructor used when cube is created
Box(double len) {
width = height = depth = len;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
// Here, Box is extended to include weight.
class BoxWeight extends Box {
double weight; // weight of box
// constructor for BoxWeight
BoxWeight(double w, double h, double d, double m) {
width = w;
height = h;
depth = d;
weight = m;
}
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 superclass reference variable, you will
have access only to those parts of the object defined by the superclass. 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 superclass has no knowledge
5. Page 5 of 30
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 it does not define one.
Using super
In the preceding examples, classes derived from Box were not implemented as efficiently or as robustly as they could
have been. For example, the constructor for BoxWeight explicitly initializes the width, height, and depth fields of Box( ).
Not only does this duplicate code found in its superclass, which is inefficient, but it implies that a subclass must be
granted access to these members. However, there will be times when you will want to create a superclass that keeps the
details of its implementation to itself (that is, that keeps its data members private). In this case, there would be no way
for a subclass to directly access or initialize these variables on its own. Since encapsulation is a primary attribute of OOP,
it is not surprising that Java provides a solution to this problem. Whenever a subclass needs to refer to its immediate
superclass, it can do so by use of the keyword super.
super has two general forms.
1. The first calls the superclass’ constructor.
2. The second is used to access a member of the superclass that has been hidden by a member of a subclass.
Using super to Call Superclass Constructors
A subclass can call a constructor method defined by its superclass by use of the following form of super:
super(parameter-list);
Here, parameter-list specifies any parameters needed by the constructor in the superclass. super( ) must always be the
first statement executed 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 superclass constructor, must be the first statement
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. This leaves Box free to make these values private if desired. 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 superclass. The constructor executed will be the one that matches the arguments. For example,
here is a complete implementation of BoxWeight that provides constructors for the various ways that a box can be
constructed. In each case, super( ) is called using the appropriate arguments. Notice that width, height, and depth have
been made private within Box.
6. Page 6 of 30
// A complete implementation of BoxWeight.
class Box {
private double width;
private double height;
private double depth;
// construct clone of an object
Box(Box ob) { // pass object to constructor
width = ob.width;
height = ob.height;
depth = ob.depth;
}
// constructor used when all dimensions specified
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
// constructor used when no dimensions specified
Box() {
width = -1; // use -1 to indicate
height = -1; // an uninitialized
depth = -1; // box
}
// constructor used when cube is created
Box(double len) {
width = height = depth = len;
}
// compute and return volume
double volume() {
return width * height * depth;
}
}
// BoxWeight now fully implements all constructors.
class BoxWeight extends Box {
double weight; // weight of box
// construct clone of an object
BoxWeight(BoxWeight ob) { // pass object to constructor
super(ob);
weight = ob.weight;
}
// constructor when all parameters are specified
BoxWeight(double w, double h, double d, double m) {
super(w, h, d); // call superclass constructor
weight = m;
}
// default constructor
BoxWeight() {
super();
weight = -1;
}
// constructor used when cube is created
BoxWeight(double len, double m) {
super(len);
weight = m;
}
7. Page 7 of 30
}
class DemoSuper {
public static void main(String args[]) {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
BoxWeight mybox3 = new BoxWeight(); // default
BoxWeight mycube = new BoxWeight(3, 2);
BoxWeight myclone = new BoxWeight(mybox1);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.println("Weight of mybox1 is " + mybox1.weight);
System.out.println();
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.println("Weight of mybox2 is " + mybox2.weight);
System.out.println();
vol = mybox3.volume();
System.out.println("Volume of mybox3 is " + vol);
System.out.println("Weight of mybox3 is " + mybox3.weight);
System.out.println();
vol = myclone.volume();
System.out.println("Volume of myclone is " + vol);
System.out.println("Weight of myclone is " + myclone.weight);
System.out.println();
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
System.out.println("Weight of mycube is " + mycube.weight);
System.out.println();
}
}
This program generates the following output:
Volume of mybox1 is 3000.0
Weight of mybox1 is 34.3
Volume of mybox2 is 24.0
Weight of mybox2 is 0.076
Volume of mybox3 is -1.0
Weight of mybox3 is -1.0
Volume of myclone is 3000.0
Weight of myclone is 34.3
Volume of mycube is 27.0
Weight of mycube is 2.0
Pay special attention to this constructor in BoxWeight( ):
// construct clone of an object
BoxWeight(BoxWeight ob) { // pass object to constructor
super(ob);
weight = ob.weight;
}
Notice that super( ) is called with an object of type BoxWeight—not of type Box. This still invokes the constructor
Box(Box ob). As mentioned earlier, a superclass variable can be used to reference any object derived from that class.
8. Page 8 of 30
Thus, we are able to pass a BoxWeight object to the Box constructor. Of course, Box only has knowledge of its own
members.
Let’s review the key concepts behind super( ). When a subclass calls super( ), it is calling the constructor of its immediate
superclass. Thus, super( ) always refers to the superclass immediately above the calling class. This is true even in a
multileveled hierarchy. Also, super( ) must always be the first statement executed inside a subclass constructor.
A Second Use for super
The second form of super acts somewhat like this, except that it always refers to the superclass 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 situations
in which member names of a subclass hide members by the same name in the superclass. Consider this simple class
hierarchy:
// Using super to overcome name hiding.
class A {
int i;
}
// Create a subclass by extending class A.
class B extends A {
int i; // this i hides the i in A
B(int a, int b) {
super.i = a; // i in A
i = b; // i in B
}
void show() {
System.out.println("i in superclass: " + super.i);
System.out.println("i in subclass: " + i);
}
}
class UseSuper {
public static void main(String args[]) {
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 superclass. As you will
see, super can also be used to call methods that are hidden by a subclass.
Multilevel Inheritance
There exists basically three types of inheritance.
1. Multilevel inheritance
2. Multiple inheritance
3. Hierarchical inheritance
9. Page 9 of 30
In single inheritance, one class extends one class only. In multilevel inheritance, the ladder of single inheritance
increases. In multiple inheritance, one class directly extends more than one class and in hierarchical inheritance one
class is extended by more than one class. Let us go in detail programmatically.
1. Multilevel Inheritance
In multilevel, one-to-one ladder increases. Multiple classes are involved in inheritance, but one class extends only one.
The lowermost subclass can make use of all its super classes' members. Multilevel inheritance is an indirect way of
implementing multiple inheritance. Following program explains.
class Aves
{
public void nature()
{
System.out.println("Generally, Aves fly");
}
}
class Bird extends Aves
{
public void eat()
{
System.out.println("Eats to live");
}
}
public class Parrot extends Bird
{
public void food()
{
System.out.println("Parrot eats seeds and fruits");
}
public static void main(String args[])
{
Parrot p1 = new Parrot();
p1.food(); // calling its own
p1.eat(); // calling super class Bird method
p1.nature(); // calling super class Aves method
}
}
Output screen of Parrot.java
Now, Parrot has two super classes Bird and Aves; but extended one-to-one. Parrot can make use of the methods of Bird
and Aves. Bird can make use of the methods of Aves, but Parrot as a super class cannot access subclass members.
Following figure gives a schematic representation of the multilevel hierarchy with the classes involved in the program.
10. Page 10 of 30
2. Multiple Inheritance
In multiple inheritance, one class extends multiple classes. Java does not support multiple inheritance but C++
supports. The above program can be modified to illustrate multiple inheritance. The following program does not work.
calss Aves { }
class Bird { }
public class Parrot extends Aves, Bird { }
In the above code, Parrot extends both Aves and Bird. This is not supported by Java and the above code raises
compilation error. Following is the schematic representation.
Note: Java supports multiple inheritance partially through interfaces.
3. Hierarchical Inheritance
In hierarchical type of inheritance, one class is extended by many subclasses. It is one-to-many relationship. A realtime
example is available at dynamic binding.
class Aves
{
public void fly()
{
System.out.println("Generally, aves fly");
}
}
class Parrot extends Aves
{
public void eat()
{
System.out.println("Parrot eats fruits and seeds");
11. Page 11 of 30
}
}
class Vulture extends Aves
{
public void vision()
{
System.out.println("Vulture can see from high altitudes");
}
}
public class FlyingCreatures
{
public static void main(String args[])
{ // all the following code is composition for FlyingCreatures
Parrot p1 = new Parrot();
p1.eat(); // calling its own member
p1.fly();
// calling super class member by
inheritance
Vulture v1 = new Vulture();
v1.vision(); // calling its own member
v1.fly(); // calling super class member by inheritance
}
}
Output screen of FlyingCreatures.java
In the above code, Aves class is extended by two classes – Parrot and Vulture. Both classes can make use of the
methods of Aves. Even though the Parrot and Vulture are subclasses of the same class Aves, but still they cannot make
use of each other members. Parrot and Vulture are known as "siblings". Siblings are disjoint and they cannot make use
of other members as between them no inheritance is involved (like two sons of a father; one son's property cannot be
shared by other but both can share the property of father). Following is the schematic representation of the classes
involved.
Dynamic binding and dynamic polymorphism use hierarchical inheritance.
Disadvantages of Inheritance
1. Both classes (super and subclasses) are tightly-coupled.
2. As they are tightly coupled (binded each other strongly with extends keyword), they cannot work independently
of each other.
12. Page 12 of 30
3. Changing the code in super class method also affects the subclass functionality.
4. If super class method is deleted, the code may not work as subclass may call the super class method with super
keyword. Now subclass method behaves independently.
Another example Multilevel Inheritance in java where we are calling constructors of super class
Class student
{
int rollno;
String name;
student(int r, String n)
{
rollno = r;
name = n;
}
void dispdatas()
{
System.out.println("Rollno = " + rollno);
System.out.println("Name = " + name);
}
}
class marks extends student
{
int total;
marks(int r, String n, int t)
{
super(r,n); //call super class (student) constructor
total = t;
}
void dispdatam()
{
dispdatas(); // call dispdatap of student class
System.out.println("Total = " + total);
}
}
class percentage extends marks
{
int per;
percentage(int r, String n, int t, int p)
{
super(r,n,t); //call super class(marks) constructor
per = p;
}
void dispdatap()
{
dispdatam(); // call dispdatap of marks class
System.out.println("Percentage = " + per);
}
}
class Multi_Inhe
{
public static void main(String args[])
{
percentage stu = new percentage(1912, "SAM", 350, 50); //call constructor
percentage
stu.dispdatap(); // call dispdatap of percentage class
}
}
13. Page 13 of 30
Output :
Rollno = 1912
Name = SAM
Total = 350
Percentage = 50
It is common that a class is derived from another derived class.
The class student serves as a base class for the derived class marks, which in turn serves as a base class for the derived
class percentage.
The class marks is known as intermediated base class since it provides a link for the inheritance between student and
percentage.
The chain is known as inheritance path.
When this type of situation occurs, each subclass inherits all of the features found in all of its super classes. In this case,
percentage inherits all aspects of marks and student.
When a class hierarchy is created, in what order are the constructors for the classes that make up
the hierarchy called?
Example :
class X
{
X()
{
System.out.println("Inside X's constructor.");
}
}
class Y extends X // Create a subclass by extending class A.
{
Y()
{
System.out.println("Inside Y's constructor.");
}
}
class Z extends Y // Create another subclass by extending B.
{
Z()
{
System.out.println("Inside Z's constructor.");
}
}
public class CallingCons
{
public static void main(String args[])
{
Z z = <span class="IL_AD" id="IL_AD1">new Z</span>();
}
}
14. Page 14 of 30
Output:
Inside X's constructor.
Inside Y's constructor.
Inside Z's constructor.
The answer is that in a class hierarchy, constructors are called in order of derivation, from superclass 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 parameterless constructor of each superclass will be executed.
As you can see from the output the constructors are called in order of derivation.
If you think about it, it makes sense that constructors are executed in order of derivation.
Because a superclass 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.
Method overriding :
Defining a method in the subclass that has the same name, same arguments and same return type as a method in the
superclass and it hides the super class method is called method overriding.
Now when the method is called, the method defined in the subclass is invoked and executed instead of the one in the
superclass.
class Xsuper
{
int y;
Xsuper(int y)
{
this.y=y;
}
void display()
{
System.out.println("super y = " +y);
}
}
class Xsub extends Xsuper
{
int z;
Xsub(int z , int y)
{
super(y);
this.z=z;
}
void display()
{
System.out.println("super y = " +y);
System.out.println("sub z = " +z);
}
}
public class TestOverride
15. Page 15 of 30
{
public static void main(String[] args)
{
Xsub s1 = new Xsub(100,200);
s1.display();
}
}
Output :
super y = 200
sub z = 100
Here the method display() defined in the subclass is invoked.
Overloading VS Overriding :
Methodoverloading is comiple time polymorphism.
Method overriding is run time polymorphism.
Overloading a method is a way to provide more than one method in one class which have same name but different
argument to distinguish them.
Defining a method in the subclass that has the same name, same arguments and same return type as a method in the
superclass is called method overriding.
Example of overriding is as above.
Method overloading in java(Recap)
Method overloading:
A class can contain any number of methods. Methods can be with parameter and without parameter.
The parameter in a method are called type signature.
It is possible in java to define two or more methods within the same class that share the same name, but with different
parameter declarations (type signatures).
When this is the case, the methods are said to be overloaded, and the process is referred to as method overloading.
Overloading methods demonstrate the concept of polymorphism.
When an overloaded method is invoked, java uses the type and/or number of arguments as its guide to determine which
version of the overloaded method to call.
Thus, overloaded methods must differ in the type and/or number of their parameters.
Overloaded methods may have different return types.
16. Page 16 of 30
When java encounters a call to an overloaded method, it simply executes the version of the method whose parameters
match the arguments used in the call.
Example :
public class MethodOver
{
int n1;
int n2;
MethodOver()
{
n1 = 10;
n2 = 20;
}
void square()
{
System.out.println("The Square is " + n1 * n2);
}
void square(int p1)
{
n1 = p1;
System.out.println("The Square is " + n1 * n2);
}
void square(int p1, int p2)
{
n1 = p1;
n2 = p2;
System.out.println("The Square is " + n1 * n2);
}
public static void main(String args[])
{
MethodOver obj1 = new MethodOver();
obj1.square(); //call non parameterise method
obj1.square(4); //call method which has 1 argument
obj1.square(7,8); //call method which has 2 argument
}
}
Output :
The Square is 200
The Square is 80
The Square is 56
You can see that here we have 3 square methods with different argument. Its called method overloading.
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.
Dynamic method dispatch is important because this is how Java implements run-time polymorphism.
method to execution based upon the type of the object being referred to at the time the call occurs. Thus, this
determination is made at run time.
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.
17. Page 17 of 30
Example :
class A
{
void callme()
{
System.out.println("Inside A's callme method");
}
}
class B extends A
{
// override callme()
void callme()
{
System.out.println("Inside B's callme method");
}
}
class C extends A
{
// override callme()
void callme()
{
System.out.println("Inside C's callme method");
}
}
public class Dynamic_disp
{
public static void main(String args[])
{
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
A r; // obtain a reference of type A
r = a; // r refers to an A object
r.callme(); // calls A's version of callme
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
r = c; // r refers to a C object
r.callme(); // calls C's version of callme
}
}
Output :
Inside A's callme method
Inside B's callme method
Inside C's callme method
Here reference of type A, called r, is declared.
The program then assigns a reference to each type of object to r and uses that reference to invoke callme( ).
As the output shows, the version of callme( ) executed is determined by the type of object being referred to at the time
of the call.
18. Page 18 of 30
Applying Method Overriding
The following program creates a superclass called Figure that stores the 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.
// Using run-time polymorphism.
class Figure {
double dim1;
double dim2;
Figure(double a, double b) {
dim1 = a;
dim2 = b;
}
double area() {
System.out.println("Area for Figure is undefined.");
return 0;
}
}
class Rectangle extends Figure {
Rectangle(double a, double b) {
super(a, b);
}
// override area for rectangle
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Figure {
Triangle(double a, double b) {
super(a, b);
}
// override area for right triangle
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class FindAreas {
public static void main(String args[]) {
Figure f = new Figure(10, 10);
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref;
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
figref = f;
System.out.println("Area is " + figref.area());
}
}
The output from the program is shown here:
Inside Area for Rectangle.
Area is 45
19. Page 19 of 30
Inside Area for Triangle.
Area is 40
Area for Figure is undefined.
Area is 0
Through the dual mechanisms of inheritance and run-time polymorphism, it is possible to define one consistent
interface that is used by several different, yet related, types of objects. In this case, if an object is derived from Figure,
then its area can be obtained by calling area( ). The interface to this operation is the same no matter what type of figure
is being used.
Abstract Classes
There are situations in which you will want to define a superclass that declares the structure of a given abstraction
without providing a complete implementation of every method. That is, sometimes 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. This is the case with the
class Figure used in the preceding example. The definition of area( ) is simply a placeholder. It will not compute and
display the area of any type of object.
As you will see as you create your own class libraries, it is not uncommon for a method to have no meaningful definition
in the context of its superclass. You can handle this situation two ways. One way, as shown in the previous example, is to
simply have it report a warning message. While this approach can be useful in certain situations—such as debugging—it
is not usually appropriate. You may have methods which must be overridden by the subclass in order for the subclass to
have any meaning.
Some Points To Note Regarding Abstract Class/Method:-
When the keyword abstract appears in a class definition, it means that zero or more of it’s methods
are abstract.
An abstract method has no body.
Some of the subclass has to override it and provide the implementation.
Objects cannot be created out of abstract class.
Abstract classes basically provide a guideline for the properties and methods of an object.
In order to use abstract classes, they have to be subclassed.
There are situations in which you want to define a superclass that declares the structure of a given
abstraction without providing a complete implementation of every method.
That is, sometimes you want to create a superclass that only defines generalized form that will be
shared by all of its subclasses, leaving it to each subclass to fill in the details.
Consider the class Triangle. It has no meaning if area( ) is not defined. In this case, you want some way to ensure that a
subclass does, indeed, override all necessary methods.Java’s solution to this problem is the abstract method. You 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);
20. Page 20 of 30
As you can see, no method body is present. 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. Such objects would be useless, because an abstract class is not fully defined. 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. Here is a simple example of a
class with an abstract method, followed by a class which implements that method:
// A Simple demonstration of abstract.
abstract class A {
abstract void callme();
// concrete methods are still allowed in abstract classes
void callmetoo() {
System.out.println("This is a concrete method.");
}
}
class B extends A {
void callme() {
System.out.println("B's implementation of callme.");
}
}
class AbstractDemo {
public static void main(String args[]) {
B b = new B();
b.callme();
b.callmetoo();
}
}
Notice that no objects of class A are declared in the program. As mentioned, it is not possible to instantiate an abstract
class. One other point: class A implements a concrete method called callmetoo( ). This is perfectly acceptable. Abstract
classes can include as much implementation as they see fit. Although abstract classes cannot be used to instantiate
objects, they can be used to create object references, because Java’s approach to run-time polymorphism is
implemented through the use of superclass 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.
You will see this feature put to use in the next example.
Using an abstract class, you can improve the Figure class shown earlier. Since there is no meaningful concept of area for
an undefined two-dimensional figure, the following version of the program declares area( ) as abstract inside Figure.
This, of course, means that all classes derived from Figure must override area( ).
// Using abstract methods and classes.
abstract class Figure {
double dim1;
double dim2;
Figure(double a, double b) {
dim1 = a;
dim2 = b;
}
// area is now an abstract method
21. Page 21 of 30
abstract double area();
}
class Rectangle extends Figure {
Rectangle(double a, double b) {
super(a, b);
}
// override area for rectangle
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
class Triangle extends Figure {
Triangle(double a, double b) {
super(a, b);
}
// override area for right triangle
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
class AbstractAreas {
public static void main(String args[]) {
// Figure f = new Figure(10, 10); // illegal now
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref; // this is OK, no object is created
figref = r;
System.out.println("Area is " + figref.area());
figref = t;
System.out.println("Area is " + figref.area());
}
}
As the comment inside main( ) indicates, it is no longer possible to declare objects of type Figure, since it is now
abstract. And, all subclasses of Figure must override area( ). To prove this to yourself, try creating a subclass that does
not override area( ). You will receive a compile-time error. Although it is not possible to create an object of type Figure,
you can create a reference variable of type Figure. The variable figref is declared as a reference to Figure, which means
that it can be used to refer to an object of any class derived from Figure. As explained, it is through superclass reference
variables that overridden methods are resolved at run time.
Abstract Method
An abstract method is method that have no body
Syntax :
abstract type name(parameter-list);
As you can see, no method body is present.
22. Page 22 of 30
Some Points To Note Regarding Abstract Class/Method:-
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.
Any subclass of an abstract class must either implement all of the abstract methods of the superclass,
or be itself declared abstract.
Example:
abstract class A1
{
abstract void displayb1();
void displaya1()
{
System.out.println("This is a concrete method");
}
}
class B1 extends A1
{
void displayb1()
{
System.out.println("B1's implementation");
}
}
public class Abstract_Demo
{
public static void main(String args[])
{
B1 b = new B1();
b.displayb1();
b.displaya1();
}
}
Output :
B1's implementation
This is a concrete method
Using final with Inheritance
The keyword 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.
Using final to Prevent Overriding
While method overriding is one of Java’s most powerful features, there will be times when you will want to prevent it
from occurring. To disallow a method from being overridden, specify final as a modifier at the start of its declaration.
Methods declared as final cannot be overridden. The following fragment illustrates final:
23. Page 23 of 30
class A {
final void meth() {
System.out.println("This is a final method.");
}
}
class B extends A {
void meth() { // ERROR! Can't override.
System.out.println("Illegal!");
}
}
Because meth( ) is declared as final, it cannot be overridden in B. If you attempt to do so, a compile-time error will
result.
Using final to Prevent Inheritance
Sometimes you will want to prevent a class from being inherited. To do this, precede the class declaration with final.
Declaring a class as final implicitly declares all of its methods as final, too. As you might expect, 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.
Here is an example of a final class:
final class A {
// ...
}
// The following class is illegal.
class B extends A { // ERROR! Can't subclass A
// ...
}
As the comments imply, it is illegal for B to inherit A since A is declared as final.
Java Interface
Interfaces are similar to abstract classes, but differ in their functionality.
In interfaces, none of the methods are implemented means interfaces defines methods without body.
Interfaces are syntactically similar to classes, but they lack instance variables, and their methods are
declared without any body.
But, it can contain final variables, which must be initialized with values.
Once it is defined, any number of classes can implement an interface.
One class can implement any number of interfaces.
If we are implementing an interface in a class we must implement all the methods defined in the interface as
well as a class can also implement its own methods.
Interfaces add most of the functionality that is required for many applications which would normally resort
to using multiple inheritance in C++.
Defining interfaces in java with syntax:
Syntax :
[Access-specifier] interface interface-name
{
Access-specifier return-type method-name(parameter-list);
final type var1=value;
}
24. Page 24 of 30
Where, Access-specifier is either public or it is not given.
When no access specifier is used, it results into default access specifier and if interface has default access specifier
then it is only available to other members of the same package.
When it is declared as public, the interface can be used by any other code of other package.
Interface-Name: name of an interface, it can be any valid identifier.
The methods which are declared having no bodies they end with a semicolon after the parameter list. Actually they
are abstract methods;
Any class that includes an interface must implement all of the methods. Variables can be declared inside interface
declarations.
They are implicitly final and static, means they can not be changed by implementing it in a class.
They must also be initialized with a constant value.
Example :
interface Item
{
static final int code = 100;
static final String name = "Fan";
void display ( );
}
interface Area
{
static final float pi = 3.14F;
float compute ( float x, float y );
void show ( );
}
Implementing interfaces
Once an interface has been defined, one or more classes can implement that interface.
To implement an interface, include the implements clause in a class definition, and then create the methods
declared by the interface.
The general form of a class that includes the implements clause looks like this:
Access-specifier class classname [extends superclass] [implements interface, [,
interface..]]
{
// class body
}
If a class implements from more than one interface, names are separated by comma.
If a class implements two interfaces that declare the same method, then the same method will be used by clients of
either interface.
25. Page 25 of 30
The methods that implement an interface must be declared as public.
The type-signature of implementing method must match exactly the type signature specified in the interface.
Example 1:
interface religion
{
String city = new String("Amritsar");
void greet();
void pray();
}
class gs implements religion
{
public void greet()
{
System.out.println("We greet - ABCD");
}
public void pray()
{
System.out.println("We pray at " + city + " XYZ ");
}
}
class iface1
{
public static void main(String args[])
{
gs sikh = new gs();
sikh.greet();
sikh.pray();
}
}
Output :
We greet - ABCD
We pray at Amritsar XYZ
Example 2 :
interface i1
{
void dispi1();
}
interface i2
{
void dispi2();
}
class c1 implements i1
{
public void dispi1()
{
System.out.println("This is display of i1");
}
}
26. Page 26 of 30
class c2 implements i2
{
public void dispi2()
{
System.out.println("This is display of i2");
}
}
class c3 implements i1, i2
{
public void dispi1()
{
System.out.println("This is display of i1");
}
public void dispi2()
{
System.out.println("This is display of i2");
}
}
class iface2
{
public static void main(String args[])
{
c1 c1obj = new c1();
c2 c2obj = new c2();
c3 c3obj = new c3();
c1obj.dispi1();
c2obj.dispi2();
c3obj.dispi1();
c3obj.dispi2();
}
}
Output :
This is display of i1
This is display of i2
This is display of i1
This is display of i2
Example 3 : // Implementing interface having common function name
interface i1
{
void disp();
}
interface i2
{
void disp();
}
class c implements i1, i2
{
public void disp()
{
System.out.println("This is display .. ");
}
}
27. Page 27 of 30
class iface7
{
public static void main(String args[])
{
c cobj = new c();
cobj.disp();
}
}
Output :
This is display ..
Note : When implementing an interface method, it must be declared as public. It is possible for classes that implement
interfaces to define additional members of their own.
Partial Implementation of Interface :
If we want to implement an interface in a class we have to implement all the methods defined in the interface.
But if a class implements an interface but does not fully implement the method defined by that interface, then that
class must be declared as abstract.
Example :
interface i1
{
void disp1();
void disp2();
}
abstract class c1 implements i1
{
public void disp1()
{
System.out.println("This is display of 1");
}
}
class c2 extends c1
{
public void disp2()
{
System.out.println("This is display of 2");
}
}
class iface
{
public static void main(String args[])
{
c2 c2obj = new c2();
c2obj.disp1();
c2obj.disp2();
}
}
28. Page 28 of 30
Output :
This is display of 1
This is display of 2
interface variables
Accessing interface variable :
One can declare variable as object references that uses an interface rather than a class type.
When you call a method through one of these references, the correct version will be called based on the actual instance
of the interface being referred to.
interface AreaCal
{
final double pi = 3.14;
double areacalculation(double r);
}
class Circle implements AreaCal
{
public double areacalculation(double r)
{
double ar;
ar = pi*r*r;
return ar;
}
}
class iface3
{
public static void main(String args[])
{
double area;
AreaCal ac = new Circle();
area = ac.areacalculation(10.25);
System.out.println("Area of Circle is : " + area);
}
}
Output :
Area of Circle is : 329.89625
Here variable ac is declared to be of the interface type AreaCal, it was assigned an instance of circle. Although ac can be
used to access the areacalculation() method, it cannot access any other members of the client class. An interface
reference variable only has knowledge of the method declared by its interface declaration.
Extending interfaces
One interface can inherit another by use of 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 implementation of all methods defined within the interface inheritance.
29. Page 29 of 30
Note : Any class that implements an interface must implement all methods defined by that interface, including any that
inherited from other interfaces.
Example :
interface if1
{
void dispi1();
}
interface if2 extends if1
{
void dispi2();
}
class cls1 implements if2
{
public void dispi1()
{
System.out.println("This is display of i1");
}
public void dispi2()
{
System.out.println("This is display of i2");
}
}
public class Ext_iface
{
public static void main(String args[])
{
cls1 c1obj = new cls1();
c1obj.dispi1();
c1obj.dispi2();
}
}
Output :
This is display of i1
This is display of i2
Note : We have to define disp1() and disp2() in cls1.
Multiple inheritance using interface..
class stu
{
int rollno;
String name = new String();
int marks;
stu(int r, String n, int m)
{
rollno = r;
name = n;
marks = m;
}
}
interface i
{
30. Page 30 of 30
void display();
}
class studerived extends stu implements i
{
studerived(int r, String n, int m)
{
super(r,n,m);
}
public void display()
{
System.out.println("Displaying student details .. ");
System.out.println("Rollno = " + rollno);
System.out.println("Name = " + name);
System.out.println("Marks = " + marks);
}
}
public class Multi_inhe_demo
{
public static void main(String args[])
{
studerived obj = new studerived(1912, "Ram", 75);
obj.display();
}
}
Output :
Displaying student details ..
Rollno = 1912
Name = Ram
Marks = 75
We can make various forms of interface implementation as below