CHAPTER 6
INHERITANCE, ENCAPSULATION, POLYMORPHISM,
AND ABSTRACTION
Java Inheritance
Inheritance is one of the key features of OOP that allows us to create a new class from
an existing class.
The new class that is created is known as subclass (child or derived class) and the
existing class from where the child class is derived is known as superclass (parent or
base class).
The extends keyword is used to perform inheritance in Java. For example,
class Animal
// methods and fields
// use of extends keyword
// to perform inheritance
class Dog extends Animal
// methods and fields of Animal
// methods and fields of Dog
In the above example, the Dog class is created by inheriting the methods and fields
from the Animal class.
Here, Dog is the subclass and Animal is the superclass.
Example 1: Java Inheritance
class Animal
// field and method of the parent class
String name;
public void eat()
System.out.println("I can eat");
// inherit from Animal
class Dog extends Animal
// new method in subclass
public void display()
System.out.println("My name is " + name);
class Main
public static void main(String[] args)
// create an object of the subclass
Dog labrador = new Dog();
// access field of superclass
labrador.name = "Rohu";
labrador.display();
// call method of superclass
// using object of subclass
labrador.eat();
Output
My name is Rohu
I can eat
In the above example, we have derived a subclass Dog from superclass Animal.
Notice the statements,
labrador.name = "Rohu";
labrador.eat();
Here, labrador is an object of Dog. However, name and eat() are the members of
the Animal class.
Since Dog inherits the field and method from Animal, we are able to access the field
and method using the object of the Dog.
Java Inheritance
Implementation
is-a relationship
In Java, inheritance is an is-a relationship. That is, we use inheritance only if there
exists an is-a relationship between two classes.
For example,
Car is a Vehicle
Orange is a Fruit
Surgeon is a Doctor
Dog is an Animal
Here, Car can inherit from Vehicle, Orange can inherit from Fruit, and so on.
Method Overriding in Java Inheritance
In Example 1, we see the object of the subclass can access the method of the
superclass.
However, if the same method is present in both the superclass and subclass,
what will happen?
In this case, the method in the subclass overrides the method in the superclass. This
concept is known as method overriding in Java.
Example 2: Method overriding in Java Inheritance
class Animal
// method in the superclass
public void eat()
System.out.println("I can eat");
// Dog inherits Animal
class Dog extends Animal
// overriding the eat() method
@Override
public void eat()
System.out.println("I eat dog food");
// new method in subclass
public void bark() {
System.out.println("I can bark");
class Main
{
public static void main(String[] args)
// create an object of the subclass
Dog labrador = new Dog();
// call the eat() method
labrador.eat();
labrador.bark();
Output
I eat dog food
I can bark
In the above example, the eat() method is present in both the
superclass Animal and the subclass Dog.
Here, we have created an object labrador of Dog.
Now when we call eat() using the object labrador, the method inside Dog is called.
This is because the method inside the derived class overrides the method inside the
base class.
This is called method overriding.
Note: We have used the @Override annotation to tell the compiler that we are
overriding a method. However, the annotation is not mandatory.
The super Keyword in Java Inheritance
Previously we saw that the same method in the subclass overrides the
method in superclass.
In such a situation, the super keyword is used to call the method of the parent
class from the method of the child class.
Example 3: super Keyword in Inheritance
class Animal
// method in the superclass
public void eat()
System.out.println("I can eat");
// Dog inherits Animal
class Dog extends Animal
// overriding the eat() method
@Override
public void eat()
// call method of superclass
super.eat();
System.out.println("I eat dog food");
// new method in subclass
public void bark()
{
System.out.println("I can bark");
class Main
public static void main(String[] args)
// create an object of the subclass
Dog labrador = new Dog();
// call the eat() method
labrador.eat();
labrador.bark();
Output
I can eat
I eat dog food
I can bark
In the above example, the eat() method is present in both the base
class Animal and the derived class Dog. Notice the statement,
super.eat();
Here, the super keyword is used to call the eat() method present in the
superclass.
We can also use the super keyword to call the constructor of the superclass
from the constructor of the subclass.
protected Members in Inheritance
In Java, if a class includes protected fields and methods, then these fields and methods
are accessible from the subclass of the class.
Example 4: protected Members in Inheritance
class Animal
protected String name;
protected void display()
System.out.println("I am an animal.");
class Dog extends Animal
public void getInfo()
System.out.println("My name is " + name);
class Main
public static void main(String[] args)
{
// create an object of the subclass
Dog labrador = new Dog();
// access protected field and method
// using the object of subclass
labrador.name = "Rocky";
labrador.display();
labrador.getInfo();
Output
I am an animal.
My name is Rocky
In the above example, we have created a class named Animal. The class includes a
protected field: name and a method: display().
We have inherited the Dog class inherits Animal. Notice the statement,
labrador.name = "Rocky";
labrador.display();
Here, we are able to access the protected field and method of the superclass using
the labrador object of the subclass.
Why use inheritance?
1. The most important use of inheritance in Java is code reusability. The code that
is present in the parent class can be directly used by the child class.
2. Method overriding is also known as runtime polymorphism. Hence, we can achieve
Polymorphism in Java with the help of inheritance.
Types of inheritance
There are five types of inheritance.
1. Single Inheritance
In single inheritance, a single subclass extends from a single superclass. For
example,
Java Single Inheritance
2. Multilevel Inheritance
In multilevel inheritance, a subclass extends from a superclass and then the same
subclass acts as a superclass for another class. For example,
Java Multilevel Inheritance
3. Hierarchical Inheritance
In hierarchical inheritance, multiple subclasses extend from a single superclass. For
example,
Java Hierarchical Inheritance
4. Multiple Inheritance
In multiple inheritance, a single subclass extends from multiple superclasses. For
example,
Java Multiple Inheritance
Note: Java doesn't support multiple inheritance. However, we can achieve multiple
inheritance using interfaces.
5. Hybrid Inheritance
Hybrid inheritance is a combination of two or more types of inheritance. For example,
Java Hybrid Inheritance
Here, we have combined hierarchical and multiple inheritance to form a hybrid inheritance.
Java Encapsulation
Encapsulation is one of the key features of object-oriented programming.
Encapsulation refers to the bundling of fields and methods inside a single
class.
It prevents outer classes from accessing and changing fields and methods of
a class. This also helps to achieve data hiding.
Example 1: Java Encapsulation
class Area
// fields to calculate area
int length;
int breadth;
// constructor to initialize values
Area(int length, int breadth)
this.length = length;
this.breadth = breadth;
// method to calculate area
public void getArea()
int area = length * breadth;
System.out.println("Area: " + area);
class Main
public static void main(String[] args)
// create object of Area
// pass value of length and breadth
Area rectangle = new Area(5, 6);
rectangle.getArea();
}
Output
Area: 30
In the above example, we have created a class named Area. The main purpose of this
class is to calculate the area.
To calculate an area, we need two variables: length and breadth and a
method: getArea(). Hence, we bundled these fields and methods inside a single class.
Here, the fields and methods can be accessed from other classes as well. Hence, this is
not data hiding.
This is only encapsulation. We are just keeping similar codes together.
Note: People often consider encapsulation as data hiding, but that's not entirely true.
Encapsulation refers to the bundling of related fields and methods together. This can be used
to achieve data hiding. Encapsulation in itself is not data hiding.
Why Encapsulation?
1. In Java, encapsulation helps us to keep related fields and methods together,
which makes our code cleaner and easy to read.
2. It helps to control the values of our data fields.
For example,
class Person
private int age;
public void setAge(int age)
{
if (age >= 0)
this.age = age;
Here, we are making the age variable private and applying logic inside
the setAge() method. Now, age cannot be negative.
The getter and setter methods provide read-only or write-only access to our class
fields.
For example,
getName() // provides read-only access
setName() // provides write-only access
It helps to decouple components of a system. For example, we can encapsulate code
into multiple bundles.
These decoupled components (bundle) can be developed, tested, and debugged
independently and concurrently. And, any changes in a particular component do not
have any effect on other components.
We can also achieve data hiding using encapsulation. In the above example, if we
change the length and breadth variable into private, then the access to these fields is
restricted.
And, they are kept hidden from outer classes. This is called data hiding.
Data Hiding
Data hiding is a way of restricting the access of our data members
by hiding the implementation details.
Encapsulation also provides a way for data hiding.
We can use access modifiers to achieve data hiding.
Example 2: Data hiding using the private specifier
class Person
// private field
private int age;
// getter method
public int getAge()
return age;
// setter method
public void setAge(int age)
this.age = age;
class Main
public static void main(String[] args)
// create an object of Person
Person p1 = new Person();
// change age using setter
p1.setAge(24);
// access age using getter
System.out.println("My age is " + p1.getAge());
Output
My age is 24
In the above example, we have a private field age . Since it
is private , it cannot be accessed from outside the class.
In order to access age , we have
used public methods: getAge() and setAge() . These methods are
called getter and setter methods.
Making age private allowed us to restrict unauthorized access from
outside the class. This is data hiding.
If we try to access the age field from the Main class, we will get an
error.
// error: age has private access in Person
p1.age = 24;
Java Polymorphism
Polymorphism is an important concept of object-oriented programming. It simply means
more than one form.
That is, the same entity (method or operator or object) can perform different operations
in different scenarios.
Example: Java Polymorphism
class Polygon
// method to render a shape
public void render()
System.out.println("Rendering Polygon...");
class Square extends Polygon
// renders Square
public void render()
System.out.println("Rendering Square...");
class Circle extends Polygon
// renders circle
public void render()
System.out.println("Rendering Circle...");
class Main
public static void main(String[] args)
// create an object of Square
Square s1 = new Square();
s1.render();
// create an object of Circle
Circle c1 = new Circle();
c1.render();
Output
Rendering Square...
Rendering Circle...
In the above example, we have created a superclass: Polygon and two
subclasses: Square and Circle. Notice the use of the render() method.
The main purpose of the render() method is to render the shape. However, the process
of rendering a square is different than the process of rendering a circle.
Hence, the render() method behaves differently in different classes. Or, we can
say render() is polymorphic.
Why Polymorphism?
Polymorphism allows us to create consistent code. In the previous example, we can
also create different methods:
renderSquare() and renderCircle() to render Square and Circle, respectively.
This will work perfectly. However, for every shape, we need to create different methods.
It will make our code inconsistent.
To solve this, polymorphism in Java allows us to create a single method render() that
will behave differently for different shapes.
Note: The print() method is also an example of polymorphism. It is used to print values
of different types like char, int, string, etc.
We can achieve polymorphism in Java using the following ways:
1. Method Overriding
2. Method Overloading
3. Operator Overloading
1. Java Method Overriding
During inheritance in Java, if the same method is present in both the superclass and the
subclass. Then, the method in the subclass overrides the same method in the
superclass. This is called method overriding.
In this case, the same method will perform one operation in the superclass and another
operation in the subclass. For example,
Example 1: Polymorphism using method overriding
class Language
public void displayInfo()
System.out.println("Common English Language");
class Java extends Language
@Override
public void displayInfo()
System.out.println("Java Programming Language");
class Main
public static void main(String[] args)
// create an object of Java class
Java j1 = new Java();
j1.displayInfo();
// create an object of Language class
Language l1 = new Language();
l1.displayInfo();
Output:
Java Programming Language
Common English Language
In the above example, we have created a superclass named Language and a subclass
named Java. Here, the method displayInfo() is present in both Language and Java.
The use of displayInfo() is to print the information. However, it is printing different
information in Language and Java.
Based on the object used to call the method, the corresponding information is printed.
Working of
Java Polymorphism
Note: The method that is called is determined during the execution of the program.
Hence, method overriding is a run-time polymorphism.
2. Java Method Overloading
In a Java class, we can create methods with the same name if they differ in parameters.
For example,
void func() { ... }
void func(int a) { ... }
float func(double a) { ... }
float func(int a, float b) { ... }
This is known as method overloading in Java. Here, the same method will perform
different operations based on the parameter.
Example 3: Polymorphism using method overloading
class Pattern
// method without parameter
public void display()
{
for (int i = 0; i < 10; i++)
System.out.print("*");
// method with single parameter
public void display(char symbol)
for (int i = 0; i < 10; i++)
System.out.print(symbol);
class Main
public static void main(String[] args)
Pattern d1 = new Pattern();
// call method without any argument
d1.display();
System.out.println("\n");
// call method with a single argument
d1.display('#');
Output:
**********
##########
In the above example, we have created a class named Pattern. The class contains a
method named display() that is overloaded.
// method with no arguments
display() {...}
// method with a single char type argument
display(char symbol) {...}
Here, the main function of display() is to print the pattern. However, based on the
arguments passed, the method is performing different operations:
prints a pattern of *, if no argument is passed or
prints pattern of the parameter, if a single char type argument is passed.
Note: The method that is called is determined by the compiler. Hence, it is also known
as compile-time polymorphism.
3. Java Operator Overloading
Some operators in Java behave differently with different operands. For example,
+ operator is overloaded to perform numeric addition as well
as string concatenation, and
operators like &, |, and ! are overloaded for logical and bitwise operations.
Let's see how we can achieve polymorphism using operator overloading.
The + operator is used to add two entities. However, in Java, the + operator performs
two operations.
1. When + is used with numbers (integers and floating-point numbers), it performs
mathematical addition. For example,
int a = 5;
int b = 6;
// + with numbers
int sum = a + b; // Output = 11
2. When we use the + operator with strings, it will perform string
concatenation (join two strings). For example,
String first = "Java ";
String second = "Programming";
// + with strings
name = first + second; // Output = Java Programming
Here, we can see that the + operator is overloaded in Java to perform two
operations: addition and concatenation.
Polymorphic Variables
A variable is called polymorphic if it refers to different values under different
conditions.
Object variables (instance variables) represent the behavior of polymorphic
variables in Java. It is because object variables of a class can refer to objects
of its class as well as objects of its subclasses.
Example: Polymorphic Variables
class ProgrammingLanguage
{
public void display()
{
System.out.println("I am Programming Language.");
}
}
class Java extends ProgrammingLanguage {
@Override
public void display()
{
System.out.println("I am Object-Oriented Programming Language.");
}
}
class Main
{
public static void main(String[] args)
{
// declare an object variable
ProgrammingLanguage pl;
// create object of ProgrammingLanguage
pl = new ProgrammingLanguage();
pl.display();
// create object of Java class
pl = new Java();
pl.display();
}
}
Output:
I am Programming Language.
I am Object-Oriented Programming Language.
In the above example, we have created an object variable pl of
the ProgrammingLanguage class. Here, pl is a polymorphic variable. This is
because,
In statement
pl = new ProgrammingLanguage(), pl refer to the object of
the ProgrammingLanguage
class.
And, in statement
pl = new Java(), pl refer to the object of the Java class.
Abstraction in Java
What is Abstraction in Java?
Abstraction is the concept of object-oriented programming that “shows” only essential attributes and
“hides” unnecessary information. The main purpose of abstraction is hiding the unnecessary details from
the users. Abstraction is selecting data from a larger pool to show only relevant details of the object to the
user. It helps in reducing programming complexity and efforts. It is one of the most important concepts of
OOPs.
Abstraction in OOPs with example:
Suppose you want to create a banking application and you are asked to collect all the information
about your customer. There are chances that you will come up with following information about
the customer
Abstraction in Java
But, not all of the above information is required to create a banking application. So, you need to
select only the useful information for your banking application from that pool. Data like name,
address, tax information, etc. make sense for a banking application which is an Abstraction
example in OOPs
Since we have fetched/removed/selected the customer information from a larger pool,
the process is referred as Abstraction in OOPs. However, the same information once
extracted can be used for a wide range of applications. For instance, you can use the
same data for hospital application, job portal application, a Government database, etc.
with little or no modification. Hence, it becomes your Master Data. This is an advantage
of Abstraction in OOPs.
Difference between Abstraction and Encapsulation
Abstraction Encapsulation
Abstraction in
Object
Oriented
Encapsulation solves it
Programming
implementation level.
solves the
issues at the
design level.
Abstraction in Encapsulation means
Programming binding the code and
is about hiding data into a single unit.
unwanted
details while
showing most
essential
information.
Data
Abstraction in Encapsulation means
Java allows hiding the internal
focussing on details or mechanics
what the of how an object does
information something for security
object must reasons.
contain
What is Abstract Class?
ABSTRACT CLASS is a type of class in Java, that declare one or more abstract
methods. These classes can have abstract methods as well as concrete methods. A
normal class cannot have abstract methods. An abstract class is a class that contains at
least one abstract method. We can understand the concept by the shape example in
java.
Consider the following class hierarchy consisting of a Shape class which is inherited by
three classes Rectangle, Circle, and Triangle. The Shape class is created to save on
common attributes and methods shared by the three classes Rectangle, Circle, and
Triangle. calculateArea() is one such method shared by all three child classes and
present in Shape class.
Shape Abstraction Example
Now, assume you write code to create objects for the classes depicted above. Let’s
observe how these objects will look in a practical world. An object of the class
rectangle will give a rectangle, a shape we so commonly observed in everyday life.
An object of the class triangle will give a triangle, again a common everyday shape.
But what would an object of Class Shape look like in a practical world ??
If you observe the Shape class serves in our goal of achieving inheritance and
polymorphism. But it was not built to be instantiated. Such classes can be
labelled Abstract. An abstract java class cannot be instantiated.
Syntax:
abstract class Shape
{
// code
}
It is possible that you DO NOT label Shape class as Abstract and then instantiate it. But
such object will have no use in your code and will open a room for potential errors.
Hence this is not desirable.
What are Abstract Methods in Java?
ABSTRACT METHOD in Java, is a method that has just the method definition but does
not contain implementation. A method without a body is known as an Abstract Method.
It must be declared in an abstract class. The abstract method will never be final
because the abstract class must implement all the abstract methods.
As we all know, the formula for calculating area for rectangle, circle, & triangle is
different. The calculateArea() method will have to be overridden by the inheriting
classes. It makes no sense defining it in the Shape class, but we need to make sure
that all the inheriting classes do have the method.
Such methods can be labeled abstract.
Syntax:
abstract public void calculateArea();
For an abstract method, no implementation is required. Only the signature of the
method is defined.
Abstraction Code Example
abstract class Shape
{
abstract void calculateArea();
}
class style extends Shape
{
void calculateArea()
{
System.out.println("Area of Shape");
}
public static void main(String args[])
{
Shape obj = new style();
obj.calculateArea();
}
}
Advantages of Abstraction
The main benefit of using an Abstraction in Programming is that it allows you to
group several related classes as siblings.
Abstraction in Object Oriented Programming helps to reduce the complexity of
the design and implementation process of software.
Final Keyword in Java
The final modifier applies to classes, methods, and variables. The meaning of final
varies from context to context, but the essential idea is the same.
A final class cannot be inherited
A final variable becomes a constant and its value cannot be changed.
A final method cannot be overridden. This is done for security reasons, and these
methods are used for optimization.
Example :- To learn abstract & final keywords
Step 1) Copy the following code into an Editor.
abstract class Shape
{
final int b = 20;
public void display()
{
System.out.println("This is display method");
}
abstract public void calculateArea();
}
public class Rectangle extends Shape
{
public static void main(String args[])
{
Rectangle obj = new Rectangle();
obj.display();
//obj.b=200;
}
//public void calculateArea(){}
}
Step 2) Save , Compile & Run the code.
Step 3) Error =? The abstract method is not implemented int the class Rectangle. To fix the issue
uncomment line #18.
Step 4) Uncomment line # 16. Save & Compile the code.
Step 5) Error = ? variable b is final
When to use Abstract Methods & Abstract Class?
Abstract methods are mostly declared where two or more subclasses are also doing the
same thing in different ways through different implementations. It also extends the same
Abstract class and offers different implementations of the abstract methods.
Abstract classes help to describe generic types of behaviors and object-oriented
programming class hierarchy. It also describes subclasses to offer implementation
details of the abstract class.
Summary:
Abstraction in Programming is the process of selecting important data sets for
an Object in your software and leaving out the insignificant ones.
Once you have modeled your object using Data Abstraction in Java, the same
set of data could be used in different applications.