Unit 3: Inheritance and Polymorphism
Unit 3: Inheritance and Polymorphism: Inheritance in java, Super and sub class,
Overriding, Object class, Polymorphism, Dynamic binding, Generic programming, Casting
objects, Instance of operator, Abstract class, Interface in java, Package in java, UTIL
package.
Inheritance in Java
Java Inheritance is a fundamental concept in OOP (Object-Oriented Programming). It is
the mechanism in Java by which one class is allowed to inherit the features (fields and
methods) of another class. In Java, Inheritance means creating new classes based on
existing ones. A class that inherits from another class can reuse the methods and fields of
that class.
Example: In the following example, Animal is the base class and Dog, Cat and Cow are
derived classes that extend the Animal class.
Implementation:
// Parent class
class Animal {
void sound() {
[Link]("Animal makes a sound");
}
}
// Child class
class Dog extends Animal {
void sound() {
[Link]("Dog barks");
}
}
// Child class
class Cat extends Animal {
void sound() {
Prof [Link], Department of Computer Science Page 1
Unit 3: Inheritance and Polymorphism
[Link]("Cat meows");
}
}
// Child class
class Cow extends Animal {
void sound() {
[Link]("Cow moos");
}
}
// Main class
public class Geeks {
public static void main(String[] args) {
Animal a;
a = new Dog();
[Link]();
a = new Cat();
[Link]();
a = new Cow();
[Link]();
}
}
Output
Dog barks
Cat meows
Cow moos
Explanation:
Animal is the base class.
Dog, Cat and Cow are derived classes that extend Animal class and provide specific
implementations of the sound() method.
The Geeks class is the driver class that creates objects and demonstrates runtime
polymorphism using method overriding.
Prof [Link], Department of Computer Science Page 2
Unit 3: Inheritance and Polymorphism
Syntax
class ChildClass extends ParentClass {
// Additional fields and methods
}
Note: In Java, inheritance is implemented using the extends keyword. The class that inherits
is called the subclass (child class) and the class being inherited from is called the superclass
(parent class).
Why Use Inheritance in Java?
Code Reusability: The code written in the Superclass is common to all subclasses.
Child classes can directly use the parent class code.
Method Overriding: Method Overriding is achievable only through Inheritance. It is
one of the ways by which Java achieves Run Time Polymorphism.
Abstraction: The concept of abstraction where we do not have to provide all details,
is achieved through inheritance. Abstraction only shows the functionality to the user.
Key Terminologies Used in Java Inheritance
Class: Class is a set of objects that share common characteristics/ behavior and
common properties/ attributes. Class is not a real-world entity. It is just a template
or blueprint or prototype from which objects are created.
Super Class/Parent Class: The class whose features are inherited is known as a
superclass(or a base class or a parent class).
Sub Class/Child Class: The class that inherits the other class is known as a
subclass(or a derived class, extended class or child class). The subclass can add its
own fields and methods in addition to the superclass fields and methods.
Extends Keyword: This keyword is used to inherit properties from a superclass.
How Inheritance Works in Java?
The extends keyword is used for inheritance in Java. It enables the subclass to inherit
the fields and methods of the superclass. When a class extends another class, it means it
inherits all the non-primitive members (fields and methods) of the parent class and the
subclass can also override or add new functionality to them.
Note: The extends keyword establishes an "is-a" relationship between the child class and
the parent class. This allows a child class to have all the behavior of the parent class.
Prof [Link], Department of Computer Science Page 3
Unit 3: Inheritance and Polymorphism
Types of Inheritance in Java
Below are the different types of inheritance which are supported by Java.
Single Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Multiple Inheritance
Hybrid Inheritance
1. Single Inheritance
In single inheritance, a sub-class is derived from only one super class. It inherits the
properties and behavior of a single-parent class. Sometimes, it is also known as simple
inheritance.
Example:
//Super class
class Vehicle {
Vehicle() {
[Link]("This is a Vehicle");
}
}
// Subclass
class Car extends Vehicle {
Car() {
[Link]("This Vehicle is Car");
}
}
public class Test {
public static void main(String[] args) {
// Creating object of subclass invokes base class constructor
Car obj = new Car();
}
}
Output
This is a Vehicle
This Vehicle is Car
Prof [Link], Department of Computer Science Page 4
Unit 3: Inheritance and Polymorphism
2. Multilevel Inheritance
In Multilevel Inheritance, a derived class will be inheriting a base class and as well as the
derived class also acts as the base class for other classes.
Example:
class Vehicle {
Vehicle() {
[Link]("This is a Vehicle");
}
}
class FourWheeler extends Vehicle {
FourWheeler() {
[Link]("4 Wheeler Vehicles");
}
}
class Car extends FourWheeler {
Car() {
[Link]("This 4 Wheeler Vehicle is a Car");
}
}
public class Geeks {
public static void main(String[] args) {
Car obj = new Car(); // Triggers all constructors in order
}
}
Output
This is a Vehicle
4 Wheeler Vehicles
This 4 Wheeler Vehicle is a Car
Prof [Link], Department of Computer Science Page 5
Unit 3: Inheritance and Polymorphism
3. Hierarchical Inheritance
In hierarchical inheritance, more than one subclass is inherited from a single base class.
i.e. more than one derived class is created from a single base class. For example, cars and
buses both are vehicle
Example:
class Vehicle {
Vehicle() {
[Link]("This is a Vehicle");
}
}
class Car extends Vehicle {
Car() {
[Link]("This Vehicle is Car");
}
}
class Bus extends Vehicle {
Bus() {
[Link]("This Vehicle is Bus");
}
}
public class Test {
public static void main(String[] args) {
Car obj1 = new Car();
Bus obj2 = new Bus();
}
}
Output
This is a Vehicle
This Vehicle is Car
This is a Vehicle
This Vehicle is Bus
Prof [Link], Department of Computer Science Page 6
Unit 3: Inheritance and Polymorphism
4. Multiple Inheritances (Through Interfaces)
In Multiple inheritances, one class can have more than one superclass and inherit
features from all parent classes.
Note: that Java does not support multiple inheritances with classes. In Java, we can achieve
multiple inheritances only through Interfaces.
Example:
interface LandVehicle {
default void landInfo() {
[Link]("This is a LandVehicle");
}
}
interface WaterVehicle {
default void waterInfo() {
[Link]("This is a WaterVehicle");
}
}
// Subclass implementing both interfaces
class AmphibiousVehicle implements LandVehicle, WaterVehicle {
AmphibiousVehicle() {
[Link]("This is an AmphibiousVehicle");
}
}
public class Test {
public static void main(String[] args) {
AmphibiousVehicle obj = new AmphibiousVehicle();
[Link]();
[Link]();
}
}
Output
This is an AmphibiousVehicle
This is a WaterVehicle
This is a LandVehicle
Prof [Link], Department of Computer Science Page 7
Unit 3: Inheritance and Polymorphism
5. Hybrid Inheritance
It is a mix of two or more of the above types of inheritance. In Java, we can achieve hybrid
inheritance only through Interfaces if we want to involve multiple inheritances to
implement Hybrid inheritance.
Explanation:
class Car extends Vehicle->Single Inheritance
class Bus extends Vehicle and class Bus extends Fare->Hybrid Inheritance (since Bus
inherits from two sources, forming a combination of single + multiple inheritance).
Advantages of Inheritance in Java
Code Reusability: Inheritance allows for code reuse and reduces the amount of
code that needs to be written. The subclass can reuse the properties and methods
of the superclass, reducing duplication of code.
Abstraction: Inheritance allows for the creation of abstract classes that define a
common interface for a group of related classes. This promotes abstraction and
encapsulation, making the code easier to maintain and extend.
Class Hierarchy: Inheritance allows for the creation of a class hierarchy, which can
be used to model real-world objects and their relationships.
Polymorphism: Inheritance allows for polymorphism, which is the ability of an
object to take on multiple forms. Subclasses can override the methods of the
superclass, which allows them to change their behavior in different ways.
Disadvantages of Inheritance in Java
Complexity: Inheritance can make the code more complex and harder to
understand. This is especially true if the inheritance hierarchy is deep or if multiple
inheritances is used.
Tight Coupling: Inheritance creates a tight coupling between the superclass and
subclass, making it difficult to make changes to the superclass without affecting the
subclass.
Prof [Link], Department of Computer Science Page 8
Unit 3: Inheritance and Polymorphism
Polymorphism in Java
Polymorphism in Java is one of the core concepts in object-oriented programming
(OOP) that allows objects to behave differently based on their specific class type. The
word polymorphism means having many forms, and it comes from the Greek
words poly (many) and morph (forms), this means one entity can take many forms. In
Java, polymorphism allows the same method or object to behave differently based on the
context, specially on the project's actual runtime class.
Key features of polymorphism:
Multiple Behaviors: The same method can behave differently depending on the
object that calls this method.
Method Overriding: A child class can redefine a method of its parent class.
Method Overloading: We can define multiple methods with the same name but
different parameters.
Runtime Decision: At runtime, Java determines which method to call depending on
the object's actual class.
Why Use Polymorphism In Java?
Using polymorphism in Java has many benefits which are listed below:
Code Reusability: Polymorphism allows the same method or class to be used with
different types of objects, which makes the code more useable.
Flexibility: Polymorphism enables object of different classes to be treated as objects of
a common superclass, which provides flexibility in method execution and object
interaction.
Abstraction: It allows the use of abstract classes or interfaces, enabling you to work
with general types (like a superclass or interface) instead of concrete types (like
specific subclasses), thus simplifying the interaction with objects.
Dynamic Behavior: With polymorphism, Java can select the appropriate method to call
at runtime, giving the program dynamic behavior based on the actual object type rather
than the reference type, which enhances flexibility.
Prof [Link], Department of Computer Science Page 9
Unit 3: Inheritance and Polymorphism
Types of Polymorphism in Java
In Java Polymorphism is mainly divided into two types:
1. Compile-Time Polymorphism (Static)
2. Runtime Polymorphism (Dynamic)
1. Compile-Time Polymorphism
Compile-Time Polymorphism in Java is also known as static polymorphism and also known
as method overloading. This happens when multiple methods in the same class have the
same name but different parameters.
Note: But Java doesn't support the Operator Overloading.
Method Overloading
As we discussed above, Method overloading in Java means when there are multiple
functions with the same name but different parameters then these functions are said to be
overloaded. Functions can be overloaded by changes in the number of arguments or/and a
change in the type of arguments.
Prof [Link], Department of Computer Science Page 10
Unit 3: Inheritance and Polymorphism
Example: Method overloading by changing the number of arguments
// Method overloading By using
// Different Types of Arguments
// Class 1
// Helper class
class Helper {
// Method with 2 integer parameters
static int Multiply(int a, int b)
{
// Returns product of integer numbers
return a * b;
}
// Method 2
// With same name but with 2 double parameters
static double Multiply(double a, double b)
{
// Returns product of double numbers
return a * b;
}
}
// Class 2
// Main class
class Geeks
{
// Main driver method
public static void main(String[] args) {
// Calling method by passing
// input as in arguments
[Link]([Link](2, 4));
[Link]([Link](5.5, 6.3));
}
}
Output
8
34.65
Explanation: The Multiply method is overloaded with different parameter types. The
compiler picks the correct method during compile time based on the arguments.
Prof [Link], Department of Computer Science Page 11
Unit 3: Inheritance and Polymorphism
2. Runtime Polymorphism
Runtime Polymorphism in Java known as Dynamic Method Dispatch. It is a process in
which a function call to the overridden method is resolved at Runtime. This type of
polymorphism is achieved by Method Overriding. Method overriding, on the other hand,
occurs when a derived class has a definition for one of the member functions of the base
class. That base function is said to be overridden.
Method Overriding
Method overriding in Java means when a subclass provides a specific implementation of a
method that is already defined in its superclass. The method in the subclass must have the
same name, return type, and parameters as the method in the superclass. Method
overriding allows a subclass to modify or extend the behavior of an existing method in the
parent class. This enables dynamic method dispatch, where the method that gets executed
is determined at runtime based on the object's actual type.
Example: This program demonstrates method overriding in Java, where the Print()
method is redefined in the subclasses (subclass1 and subclass2) to provide specific
implementations.
// Java Program for Method Overriding
// Class 1
// Helper class
class Parent {
// Method of parent class
void Print() {
[Link]("parent class");
}
}
// Class 2
// Helper class
class subclass1 extends Parent {
// Method
void Print() {
[Link]("subclass1");
}
}
// Class 3
// Helper class
class subclass2 extends Parent {
Prof [Link], Department of Computer Science Page 12
Unit 3: Inheritance and Polymorphism
// Method
void Print() {
[Link]("subclass2");
}
}
// Class 4
// Main class
class Geeks {
// Main driver method
public static void main(String[] args) {
// Creating object of class 1
Parent a;
// Now we will be calling print methods
// inside main() method
a = new subclass1();
[Link]();
a = new subclass2();
[Link]();
}
}
Output
subclass1
subclass2
Explanation: In the above example, when an object of a child class is created, then the
method inside the child class is called. This is because the method in the parent class is
overridden by the child class. This method has more priority than the parent method inside
the child class. So, the body inside the child class is executed.
Advantages of Polymorphism
Encourages code reuse.
Simplifies maintenance.
Enables dynamic method dispatch.
Helps in writing generic code that works with many types.
Disadvantages of Polymorphism
It can make more difficult to understand the behavior of an object.
This may cause performance issues, as polymorphic behavior may require additional
computations at runtime.
Prof [Link], Department of Computer Science Page 13
Unit 3: Inheritance and Polymorphism
Generic Programming
Generic programming is a style of programming where algorithms and data structures
are written in terms of types that are specified later. This allows you to write a single
method or class that works for any data type.
In Java, this is done using type parameters (like <T>, <E>, <K, V>, etc.).
Generics means parameterized types. They allows us to write code that works with
different data types using a single class, interface or method. Instead of creating separate
versions for each type, we use type parameters (like <T>) to make the code reusable and
type-safe.
Why Use Generics?
Before Generics, Java collections like ArrayList or HashMap could store any type of
object, everything was treated as an Object. It had some problems.
If you added a String to a List, Java didn’t remember its type. You had to manually cast
it when retrieving. If the type was wrong, it caused a runtime error.
With Generics, you can specify the type the collection will hold like ArrayList<String>.
Now, Java knows what to expect and it checks at compile time, not at runtime.
Types of Java Generics
1. Generic Class: A generic class is like a regular class but uses type parameters (like
<T>). It can accept one or more types, making the class reusable for different data types.
Such classes are called parameterized classes.
2. Generic Method: A generic method is a method that can work with different data types
using a type parameter. It lets you write one method that works for all types, instead of
repeating the same logic.
Generic Class
A generic class is a class that can operate on objects of different types using a type
parameter. Like C++, we use <> to specify parameter types in generic class creation. To
create objects of a generic class, we use the following syntax:
// To create an instance of generic class
BaseType <Type> obj = new BaseType <Type>()
Note: In Parameter type, we can not use primitives like "int", "char" or "double". Use
wrapper classes like Integer, Character, etc.
Prof [Link], Department of Computer Science Page 14
Unit 3: Inheritance and Polymorphism
Example:
// We use < > to specify Parameter type
class Test<T> {
T obj;
Test(T obj) {
[Link] = obj;
}
public T getObject() { return [Link]; }
}
class Geeks {
public static void main(String[] args)
{
// instance of Integer type
Test<Integer> iObj = new Test<Integer>(15);
[Link]([Link]());
// instance of String type
Test<String> sObj
= new Test<String>("GeeksForGeeks");
[Link]([Link]());
}
}
Output
15
GeeksForGeeks
We can also pass multiple Type parameters in Generic classes.
Example: Generic Class with Multiple Type Parameters
class Test<T, U>
{
T obj1; // An object of type T
U obj2; // An object of type U
Test(T obj1, U obj2)
{
this.obj1 = obj1;
this.obj2 = obj2;
}
public void print()
Prof [Link], Department of Computer Science Page 15
Unit 3: Inheritance and Polymorphism
{
[Link](obj1);
[Link](obj2);
}
}
class Geeks
{
public static void main (String[] args)
{
Test <String, Integer> obj =
new Test<String, Integer>("GfG", 15);
[Link]();
}
}
Output
GfG
15
Generic Method
We can also write generic methods that can be called with different types of arguments
based on the type of arguments passed to the generic method. The compiler handles each
method.
Example:
class Geeks {
// A Generic method example
static <T> void genericDisplay(T element)
{
[Link]([Link]().getName()
+ " = " + element);
}
public static void main(String[] args)
{
// Calling generic method with Integer argument
genericDisplay(11);
// Calling generic method with String argument
genericDisplay("GeeksForGeeks");
Prof [Link], Department of Computer Science Page 16
Unit 3: Inheritance and Polymorphism
// Calling generic method with double argument
genericDisplay(1.0);
}
}
Output
[Link] = 11
[Link] = GeeksForGeeks
[Link] = 1.0
Limitations of Generics
1. Generics Work Only with Reference Types
When we declare an instance of a generic type, the type argument passed to the type
parameter must be a reference type. We cannot use primitive data types like int, char.
Test<int> obj = new Test<int>(20);
The above line results in a compile-time error that can be resolved using type wrappers
to encapsulate a primitive type.
But primitive type arrays can be passed to the type parameter because arrays are
reference types.
ArrayList<int[]> a = new ArrayList<>();
2. Generic Types Differ Based on their Type Arguments
During compilation, generic type information is erased which is also known as type
erasure.
Example:
class Test<T> {
// An object of type T is declared
T obj;
Test(T obj) { [Link] = obj; } // constructor
public T getObject() { return [Link]; }
}
class Geeks {
public static void main(String[] args)
{
// instance of Integer type
Test<Integer> iObj = new Test<Integer>(15);
[Link]([Link]());
// instance of String type
Test<String> sObj
Prof [Link], Department of Computer Science Page 17
Unit 3: Inheritance and Polymorphism
= new Test<String>("GeeksForGeeks");
[Link]([Link]());
iObj = sObj; // This results an error
}
}
Output:
error:
incompatible types:
Test cannot be converted to Test
Explanation: Even though iObj and sObj are of type Test, they are the references to
different types because their type parameters differ. Generics add type safety through
this and prevent errors.
Type Parameter Naming Conventions
The type parameters naming conventions are important to learn generics thoroughly. The
common type parameters are as follows:
T: Type
E: Element
K: Key
N: Number
V: Value
Benefits of Generics
Programs that use Generics has got many benefits over non-generic code.
1. Code Reuse: We can write a method/class/interface once and use it for any type we
want.( Same code can be reused for different types.)
2. Type Safety: Generics make errors to appear compile time than at run time (It's
always better to know problems in your code at compile time rather than making your
code fail at run time).( Catch errors at compile time instead of runtime)
3. Eliminates Type Casting: No need to cast objects when retrieving them.
4. Improved Readability: Code is easier to understand and maintain.
Prof [Link], Department of Computer Science Page 18
Unit 3: Inheritance and Polymorphism
Binding
Binding is a mechanism creating link between method call and method actual
implementation. As per the polymorphism concept in Java , object can have many different
forms. Object forms can be resolved at compile time and run time. If linking between
method call and method implementation is resolved at compile time then we call it static
binding or If it is resolved at run time then it dynamic binding. Dynamic binding uses object
to resolve binding but static binding use type of the class and fields.
Difference between Static binding and dynamic binding in Java
Sr. No. Key Static Binding Dynamic Binding
1 Basic It is resolved at compile time It is resolved at run time
Resolve static binding use type of the class Dynamic binding uses object to
2
mechanism and fields resolve binding
Overloading is an example of static Method overriding is the
3 Example
binding example of Dynamic binding
Type of private, final and static methods and Virtual methods use dynamic
4.
Methods variables uses static binding binding
Static Binding
The binding which can be resolved at compile time by the compiler is known as static or
early binding. The binding of all the static, private, and final methods is done at compile-
time.
Example:
// Java Program to Illustrate Static Binding
// Main class
class NewClass {
// Static nested inner class
// Class 1
public static class superclass {
// Method of inner class
static void print()
{
// Print statement
Prof [Link], Department of Computer Science Page 19
Unit 3: Inheritance and Polymorphism
[Link]("print() in superclass is called");
}
}
// Static nested inner class
// Class 2
public static class subclass extends superclass {
// Method of inner class
static void print()
{
// print statement
[Link]("print() in subclass is called");
}
}
// Method of main class
// Main driver method
public static void main(String[] args)
{
// Creating objects of static inner classes
// inside main() method
superclass A = new superclass();
superclass B = new subclass();
// Calling method over above objects
[Link]();
[Link]();
}
}
Output
print() in superclass is called
print() in superclass is called
Output Explanation: As you can see, in both cases the print method of the superclass is
called. Let us discuss how this happens
We have created one object of subclass and one object of the superclass with the
reference of the superclass.
Since the print method of the superclass is static, the compiler knows that it will not
be overridden in subclasses and hence compiler knows during compile time which
print method to call and hence no ambiguity.
Prof [Link], Department of Computer Science Page 20
Unit 3: Inheritance and Polymorphism
Dynamic Binding
In Dynamic binding compiler doesn't decide the method to be called. Overriding is a
perfect example of dynamic binding. In overriding both parent and child classes have the
same method.
Example:
// Java Program to Illustrate Dynamic Binding
// Main class
public class GFG {
// Static nested inner class
// Class 1
public static class superclass {
// Method of inner class 1
void print()
{
// Print statement
[Link](
"print in superclass is called");
}
}
// Static nested inner class
// Class 2
public static class subclass extends superclass {
// Method of inner class 2
@Override void print()
{
// Print statement
[Link](
"print in subclass is called");
}
}
// Method inside main class
public static void main(String[] args)
{
// Creating object of inner class 1
// with reference to constructor of super class
Prof [Link], Department of Computer Science Page 21
Unit 3: Inheritance and Polymorphism
superclass A = new superclass();
// Creating object of inner class 1
// with reference to constructor of sub class
superclass B = new subclass();
// Calling print() method over above objects
[Link]();
[Link]();
}
}
Output
print in superclass is called
print in subclass is called
Output Explanation: Here the output differs. But why? Let's break down the code and
understand it thoroughly.
Methods are not static in this code.
During compilation, the compiler has no idea as to which print has to be called since
the compiler goes only by referencing variable not by the type of object, and therefore
the binding would be delayed to runtime and therefore the corresponding version of
the print will be called based on type on an object.
Prof [Link], Department of Computer Science Page 22
Unit 3: Inheritance and Polymorphism
Typecasting in Java
Typecasting is the process of converting one data type to another data type.
Types of Type Casting
There are two types of Type Casting in Java:
Widening Type Casting
Narrow Type Casting
Widening Type Casting (Implicit Casting)
A lower data type is transformed into a higher one by a process known as widening type
casting. Implicit type casting and casting down are some names for it. It occurs naturally.
Since there is no chance of data loss, it is secure. Widening Type casting occurs when:
The target type must be larger than the source type.
Both data types must be compatible with each other.
Note: Widening type casting is also sometimes called upcasting for primitives, but it is not
correct to call it casting down.
Syntax:
larger_data_type variable_name = smaller_data_type_variable;
Example: Java program to demonstrate Widening TypeCasting
import [Link].*;
class Geeks {
public static void main(String[] args)
{
int i = 10;
// Wideing TypeCasting (Automatic Casting) from int to long
long l = i;
// Wideing TypeCasting (Automatic Casting) from int to double
double d = i;
[Link]("Integer: " + i);
[Link]("Long: " + l);
[Link]("Double: " + d);
}
}
Prof [Link], Department of Computer Science Page 23
Unit 3: Inheritance and Polymorphism
Output
Integer: 10
Long: 10
Double: 10.0
2. Narrow Type Casting (Explicit Casting)
The process of downsizing a bigger data type into a smaller one is known as narrowing
type casting. Casting up or explicit type casting are other names for it. It doesn't just
happen by itself. If we don't explicitly do that, a compile-time error will occur. Narrowing
type casting is unsafe because data loss might happen due to the lower data type's smaller
range of permitted values. A cast operator assists in the process of explicit casting.
Syntax:
smaller_data_type variable_name = (smaller_data_type) larger_data_type_variable;
Example: Java Program to demonstrate Narrow type casting
import [Link].*;
class Geeks {
public static void main(String[] args)
{
double i = 100.245;
// Narrowing Type Casting
short j = (short)i;
int k = (int)i;
[Link]("Original Value before Casting"+ i);
[Link]("After Type Casting to short " + j);
[Link]("After Type Casting to int "+ k);
}
}
Output
Original Value before Casting100.245
After Type Casting to short 100
After Type Casting to int 100
Prof [Link], Department of Computer Science Page 24
Unit 3: Inheritance and Polymorphism
Types of Explicit Casting
Mainly there are two types of Explicit Casting:
Explicit Upcasting
Explicit Downcasting
1. Explicit Upcasting
Upcasting is the process of casting a subtype to a supertype in the inheritance
tree's upward direction. When a sub-class object is referenced by a superclass
reference variable, an automatic process is triggered without any further effort.
Example: Java Program to demonstrate Explicit Upcasting
import [Link].*;
class Animal {
public void makeSound()
{
[Link]("The animal makes a sound");
}
}
class Dog extends Animal {
public void makeSound()
{
[Link]("The dog barks");
}
public void fetch()
{
[Link]("The dog fetches a ball");
}
}
class Geeks {
public static void main(String[] args)
{ // Upcasting
Animal animal = new Dog();
// Calls the overridden method in Dog class
[Link]();
// This would give a compile error as fetch() is not
// a method in Animal class
// [Link]();
}
}
Prof [Link], Department of Computer Science Page 25
Unit 3: Inheritance and Polymorphism
Output
The dog barks
2. Explicit Downcasting
When a subclass type refers to an object of the parent class, the process is referred to as
downcasting. If it is done manually, the compiler issues a runtime ClassCastException
error. It can only be done by using the instanceof operator. Only the downcast of an object
that has already been upcast is possible.
Example: Java Program to demonstrate Explicit downcasting
import [Link].*;
class Animal {
public void eat()
{
[Link]("The animal is eating.");
}
}
class Cat extends Animal {
public void meow()
{
[Link]("The cat is meowing.");
}
}
class Geeks {
public static void main(String[] args)
{
Animal animal = new Cat();
[Link]();
// Explicit downcasting
Cat cat = (Cat)animal;
[Link]();
}
}
Output
The animal is eating.
The cat is meowing.
Prof [Link], Department of Computer Science Page 26
Unit 3: Inheritance and Polymorphism
instanceof operator
In Java, the instanceof operator is used to test whether an object is an instance of a
specific class or subclass (or implements a specific interface). It's a binary operator that
returns a boolean value: true or false.
Syntax:
object instanceof ClassName
object: the reference to be tested.
ClassName: the class or interface you want to check against.
Example:
class Animal {}
class Dog extends Animal {}
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
[Link](a instanceof Dog); // true
[Link](a instanceof Animal); // true
[Link](a instanceof Object); // true
}
}
Key Points:
1. Checks inheritance hierarchy:
instanceof returns true if the object is an instance of the specified class or
its subclass, or implements the interface.
2. Avoid using with null:
If the reference is null, instanceof always returns false.
String s = null;
[Link](s instanceof String); // false
3. Used for safe downcasting:
Before casting an object to a subclass, use instanceof to check type compatibility:
if (a instanceof Dog) {
Dog d = (Dog) a; // Safe cast
}
4. Supports interfaces:
Works with interfaces as well:
if (obj instanceof Runnable) {
// obj implements Runnable
}
Prof [Link], Department of Computer Science Page 27
Unit 3: Inheritance and Polymorphism
Abstract Class in Java
Java abstract class is a class that can not be instantiated by itself, it needs to be subclassed
by another class to use its properties. An abstract class is declared using the "abstract"
keyword in its class definition.
Illustration of Abstract class
abstract class Shape
{
int color;
// An abstract function
abstract void draw();
}
In Java, the following some important observations about abstract classes are as follows:
1. An instance of an abstract class can not be created.
2. Constructors are allowed.
3. We can have an abstract class without any abstract method.
4. There can be a final method in abstract class but any abstract method in
class(abstract class) can not be declared as final or in simpler terms final method can
not be abstract itself as it will yield an error: "Illegal combination of modifiers:
abstract and final"
5. We can define static methods in an abstract class
6. We can use the abstract keyword for declaring top-level classes (Outer class) as
well as inner classes as abstract
7. If a class contains at least one abstract method then compulsory should declare a
class as abstract
8. If the Child class is unable to provide implementation to all abstract methods of
the Parent class then we should declare that Child class as abstract so that the next
level Child class should provide implementation to the remaining abstract method
Examples of Java Abstract Class
1. Example of Abstract Class that has Abstract method
Below is the implementation of the above topic:
// Abstract class
abstract class Sunstar {
abstract void printInfo();
}
// Abstraction performed using extends
class Employee extends Sunstar {
void printInfo()
{
String name = "Anish";
int age = 12;
float salary = 222.2F;
Prof [Link], Department of Computer Science Page 28
Unit 3: Inheritance and Polymorphism
[Link](name);
[Link](age);
[Link](salary);
}
}
// Base class
class Base {
public static void main(String args[])
{
Sunstar s = new Employee();
[Link]();
}
}
Output
Anish
12
222.2
Java Interface
An Interface in Java programming language is defined as an abstract type used to specify
the behaviour of a class. An interface in Java is a blueprint of a behaviour. A Java interface
contains static constants and abstract methods.
Key Properties of Interface:
The interface in Java is a mechanism to achieve abstraction.
By default, variables in an interface are public, static and final.
It is used to achieve abstraction and multiple inheritance in Java.
It supports loose coupling (classes depend on behavior, not implementation).
In other words, interfaces primarily define methods that other classes must
implement.
An interface in Java defines a set of behaviours that a class can implement, usually
representing a CAN-DO relationship, but not always in every scenario.
Prof [Link], Department of Computer Science Page 29
Unit 3: Inheritance and Polymorphism
Example: This example demonstrates how an interface in Java defines constants and
abstract methods, which are implemented by a class.
import [Link].*;
// Interface Declared
interface testInterface {
// public, static and final
final int a = 10;
// public and abstract
void display();
}
// Class implementing interface
class TestClass implements testInterface {
// Implementing the capabilities of Interface
public void display(){
[Link]("Geek");
}
}
class Geeks
{
public static void main(String[] args)
{
TestClass t = new TestClass();
[Link]();
[Link](t.a);
}
}
Output
Geek
10
Note: In Java, the abstract keyword applies only to classes and methods, indicating that
they cannot be instantiated directly and must be implemented. When we decide on a type of
entity by its behaviour and not via attribute we should define it as an interface.
Prof [Link], Department of Computer Science Page 30
Unit 3: Inheritance and Polymorphism
Syntax:
interface InterfaceName {
// Constant fields (public static final by default)
int CONSTANT = 10;
// Abstract method (public abstract by default)
void methodName();
// Default method (JDK 8+)
default void defaultMethod() {
[Link]("Default implementation");
}
// Static method (JDK 8+)
static void staticMethod() {
[Link]("Static method in interface");
}
// Private method (JDK 9+)
private void privateMethod() {
[Link]("Private helper method");
}
}
Note:
Private methods can only be called inside default or static methods in the interface, not
by implementing classes
Static methods are also accessible via the3interface itself not through objects
To declare an interface, use the interface keyword. It is used to provide total abstraction.
That means all the methods in an interface are declared with an empty body and are
public and all fields are public, static and final by default. A class that implements an
interface must implement all the methods declared in the interface. To implement the
interface, use the implements keyword.
Relationship Between Class and Interface
A class can extend another class and similarly, an interface can extend another interface.
However, only a class can implement an interface and the reverse (an interface
implementing a class) is not allowed
.
Prof [Link], Department of Computer Science Page 31
Unit 3: Inheritance and Polymorphism
When to Use Class and Interface?
Use a Class when:
Use a class when you need to represent a real-world entity with attributes (fields) and
behaviors (methods).
Use a class when you need to create objects that hold state and perform actions
Classes are used for defining templates for objects with specific functionality and
properties.
Use a Interface when:
Use an interface when you need to define a contract for behavior that multiple classes
can implement.
Interface is ideal for achieving abstraction and multiple inheritance.
Java Packages
Packages are used in Java in order to prevent naming conflicts, control access, make
searching/locating and usage of classes, interfaces, enumerations, and annotations easier,
etc.
A Java package can be defined as a grouping of related types
(classes, interfaces, enumerations, and annotations) providing access protection and
namespace management.
Types of Java Packages
Java packages are of two types:
1. Built-in Java Packages
2. User-defined Java Packages
Some of the existing packages in Java are −
[Link] − bundles the fundamental classes
[Link] − classes for input , output functions are bundled in this package
User-defined Java Packages
You can define your own packages to bundle groups of classes/interfaces, etc. It is a good
practice to group related classes implemented by you so that a programmer can easily
determine that the classes, interfaces, enumerations, and annotations are related.
Since the package creates a new namespace there won't be any name conflicts with names
in other packages. Using packages, it is easier to provide access control and it is also easier
to locate the related classes.
Prof [Link], Department of Computer Science Page 32
Unit 3: Inheritance and Polymorphism
Creating a Java Package
While creating a package, you should choose a name for the package and include
a package statement along with that name at the top of every source file that contains the
classes, interfaces, enumerations, and annotation types that you want to include in the
package.
The package statement should be the first line in the source file. There can be only one
package statement in each source file, and it applies to all types in the file.
If a package statement is not used then the class, interfaces, enumerations, and annotation
types will be placed in the current default package.
Compiling with Java Package
To compile the Java programs with package statements, you have to use -d option as shown
below.
javac -d Destination_folder file_name.java
Then a folder with the given package name is created in the specified destination, and the
compiled class files will be placed in that folder.
Java Package Example
Let us look at an example that creates a package called animals. It is a good practice to use
names of packages with lower case letters to avoid any conflicts with the names of classes
and interfaces.
Following package example contains interface named animals −
/* File name : [Link] */
package animals;
interface Animal {
public void eat();
public void travel();
}
Now, let us implement the above interface in the same package animals −
package animals;
/* File name : [Link] */
public class MammalInt implements Animal {
public void eat() {
[Link]("Mammal eats");
Prof [Link], Department of Computer Science Page 33
Unit 3: Inheritance and Polymorphism
}
public void travel() {
[Link]("Mammal travels");
}
public int noOfLegs() {
return 0;
}
public static void main(String args[]) {
MammalInt m = new MammalInt();
[Link]();
[Link]();
}
}
interface Animal {
public void eat();
public void travel();
}
Output
Now compile the java files as shown below −
$ javac -d . [Link]
$ javac -d . [Link]
Now a package/folder with the name animals will be created in the current directory and
these class files will be placed in it as shown below.
You can execute the class file within the package and get the result as shown below.
Mammal eats
Mammal travels
Prof [Link], Department of Computer Science Page 34
Unit 3: Inheritance and Polymorphism
Question Bank
2 Marks
1. What is inheritance in Java?
2. What are different types of inheritances?
3. Define Polymorphism
4. What are multiple inheritances in Java?
5. What do you mean by Overriding in Java?
6. What are different types of binding in Java?
7. What are static and dynamic binding in Java?
8. What is Generic Programming?
9. What is type casting in Java?
10. What is an Abstract Class?
11. What is instance of operator in Java?
12. What is an abstract class?
13. What is interface in Java?
14. Why are packages used in Java?
5/10 Marks
1. Explain Inheritance.
2. Explain Polymorphism.
3. Explain Super and sub class.
4. Explain Dynamic binding.
5. Explain Generic programming.
6. Explain Abstract class
Prof [Link], Department of Computer Science Page 35