Notes OOP Unit 3 Inheritance and Polymorphism
Notes OOP Unit 3 Inheritance and Polymorphism
1.1 Inheritance:
Introduction:
Syntax
class ChildClass extends ParentClass
{
// Additional fields and methods
}
Example:
1
class Animal { // Parent class public class Main {
void sound() { public static void main(String[] args) {
System.out.println("Animal makes a sound"); Animal a;
} a = new Dog();
} a.sound();
class Dog extends Animal { // Child class a = new Cat();
void sound() { a.sound();
System.out.println("Dog barks"); a = new Cow();
} a.sound();
} }
class Cat extends Animal { // Child class }
void sound() {
System.out.println("Cat meows"); Output:
} Dog barks
} Cat meows
class Cow extends Animal { // Child class Cow moos
void sound() { Explanation:
System.out.println("Cow moos");
} ● Animal is the base class.
} ● Dog, Cat and Cow are derived classes that
extend Animal class and provide specific
implementations of the sound() method.
Need of Inheritance:
2
Types of Inheritance:
● Single Inheritance
● Multilevel Inheritance
● Hierarchical Inheritance
● Multiple Inheritance
● Hybrid Inheritance
1. Single Inheritance
Syntax:
class BaseClass
{
// Members and methods of the base class
};
class DerivedClass extends BaseClass
{
// Members and methods of the derived class
// Inherits from BaseClass
};
//Super class // Creating object of subclass invokes base class
class Vehicle { constructor
Vehicle() { Car obj = new Car();
System.out.println("This is a Vehicle"); }
} }
}
Output
// Subclass This is a Vehicle
class Car extends Vehicle { This Vehicle is Car
Car() {
System.out.println("This Vehicle is Car"); Explanation:
} ● This program shows inheritance between a
} parent class (Vehicle) and a child class (Car).
public class Test { ● When a Car object is created, Java first calls
public static void main(String[] args) { the Vehicle constructor automatically.
● This is called constructor chaining, and it
ensures proper initialization.
● Both constructors print messages, showing the
order of execution.
3
2. Multilevel Inheritance:
● In multilevel inheritance, a class is derived from a
class which is already derived from another class. It
forms a chain of inheritance.
● Multilevel Inheritance is a type of inheritance in
C++ where one class inherits another class, which in
turn is derived from another class. It is known as
multi-level inheritance as there are more than one
level of inheritance.
● For example, if we take Grandfather as a base class
then Father is the derived class that has features of
Grandfather and then Child is the also derived class
that is derived from the sub-class Father which
inherits all the features of Father.
Syntax:
class A class C extends B
{ {
// Base class // Derived class
} }
class B extends A
{
// Intermediate class
}
Example:
4
3.Hierarchical Inheritance:
● Hierarchical inheritance is a type of inheritance in Object-Oriented Programming (OOP)
where multiple derived classes (subclasses) inherit from a single base class (superclass).
● This creates a tree-like structure where one parent class has several child classes, each
potentially adding its own unique functionalities while sharing common attributes and
methods from the base class
Syntax:
class Parent {
// Base class
}
Example:
5
4.Multiple Inheritance:(Covers point 1.5 Interface also)
● In object-oriented programming (OOP), multiple inheritance refers to
a feature where a class can inherit characteristics (methods and
properties) from more than one parent class.
● This allows a child class to combine and reuse functionality from
multiple sources.
● In Java, multiple inheritance of classes is not supported to avoid
ambiguity and complexity—especially the infamous diamond
problem.
● However, Java does support multiple inheritance through interfaces,
which allows a class to inherit behavior from multiple sources
without the pitfalls of class-based multiple inheritance.
● Ambiguity: If two parent classes have methods with the same signature, the compiler
can't decide which one to use.
● Diamond Problem: When two classes inherit from the same superclass and a third class
inherits from both, method resolution becomes unclear.
● Simplicity: Java favors clean, maintainable code through single inheritance and
interface-based design.
● Syntax:
interface A {
void methodA();
}
interface B {
void methodB();
}
class C implements A, B {
public void methodA() { }
public void methodB() { }
}
Imagine a Smartwatch that inherits features from both a Watch and a Fitness Tracker.
Parent Class 1: Watch
● Shows time
● Has alarm
6
● Stopwatch feature
Example:
7
} Each interface defines two methods, and SmartWatch
// SmartWatch-specific method provides concrete implementations for all four.
public void playMusic() { Additionally, SmartWatch has its own method
System.out.println("Playing music: 'Shape of playMusic(), showcasing how a class can extend
You' by Ed Sheeran"); functionality beyond inherited behavior.
} In main(), all methods are called sequentially,
} demonstrating how multiple inheritance via interfaces
allows a class to combine diverse behaviors.
Example 2:
5. Hybrid Inheritance :
● Hybrid inheritance is a combination of two or more
types of inheritance (like single, multiple,
hierarchical, or multilevel) in one program.
● It’s often used to demonstrate how complex
relationships between classes can be structured.
● Since Java doesn’t support multiple inheritance with
classes (to avoid ambiguity), hybrid inheritance in
Java is typically achieved using interfaces.
8
Syntax:
Interface A
↑
Class B (implements A)
↑
Class C (extends B)
↑
Class D (extends C, implements Interface E)
Example:
sp.browseInternet(); //
SmartPhone-specific
}
}
9
● Diamond Problem:
○ The primary problem with multiple inheritance is that it has the potential to create
ambiguities in child classes.
○ In a 1995 overview whitepaper, Java lead designer James Gosling stated that the
issues with multiple inheritance were one of the motivations for the creation of
Java.
○ The difficulties inherent in multiple inheritance are most clearly seen in the
diamond problem. In the diamond problem, parent class A has two distinct child
classes B and C; that is, child classes B and C extend class A.
○ Now we create a new child class D, which extends both class B and class C. Note
that we have multiple inheritance (D extends B and C), hierarchical inheritance (B
and C extend A), and multilevel inheritance (D extends A, B, and C).
○ In the diamond problem, child classes B and C inherit a method from parent class
A. Both B and C override the inherited method. But the new methods in B and C
conflict with each other.
○ Ultimate child class D inherits the two independent and conflicting methods from
its multiple parents B and C. It is unclear which method class D should use, so
there is ambiguity. Other OOP programming languages implement various
methods for addressing the multiple inheritance ambiguity.
○ Multiple inheritance in programming is a feature where a class can inherit
properties and methods from more than one parent class. This allows a class to
combine the features and behaviors of multiple classes into one. However, it can
lead to a lot of confusion when two parent classes have methods with the same
name, and it’s not clear which one the subclass should inherit. Therefore, some
languages like Java and C# do not support multiple inheritance, while others like
C++ and Python do. It’s a powerful tool, but it needs to be used with caution due
to its complexity.
10
Benefits of Inheritance:
1. Inheritance allows code reusability by enabling child classes to use methods and
properties of parent classes.
2. It improves maintainability since updates in the base class automatically reflect in derived
classes.
3. It helps organize code into a logical hierarchy that mirrors real-world relationships.
4. Inheritance supports extensibility, allowing new features to be added with minimal
changes.
5. It reduces redundancy by centralizing common code in the base class.
6. It enables polymorphism, allowing dynamic method dispatch and flexible behavior.
7. Shared behavior is encapsulated in one place, making debugging and testing easier.
Cost of Inheritance:
1. Inheritance creates tight coupling between base and derived classes, reducing modularity.
2. It can reduce flexibility, as changes in the base class may affect all subclasses.
3. Deep inheritance hierarchies can make code complex and harder to understand.
4. Constructor chaining during object creation can introduce performance overhead.
5. Misusing inheritance instead of composition can lead to poor software design.
6. Bugs in the base class can propagate to all subclasses, complicating testing.
11
1.3
1. What is a Constructor?
● A constructor is a special method in Java that is used to create and initialize objects of a
class. It has no return type and its name must be the same as the class name.
A derived class is a class that inherits properties and methods from another class, called the base
class. In Java, inheritance is implemented using the extends keyword.
When an object of a derived class is created, the constructor of the base class is executed first,
followed by the constructor of the derived class. This ensures that the base part of the object is
properly initialized before the derived part.
In Java, the super() keyword is used inside a derived class constructor to explicitly call the
constructor of the base class. This call must be the first statement in the derived class constructor.
12
If the base class has a default (no-argument) constructor, Java automatically calls it when the
derived class object is created. However, if the base class only has a parameterized constructor,
then the derived class must explicitly call it using super(arguments).
Constructors are not inherited from the base class to the derived class. Each class must define its
own constructor, but the derived class can call the base class constructor using super().
Example:
Example 1 Example 2
class A // Parent class
{ class Person {
public A() public Person() {
System.out.println("Default constructor in
{
Person");
System.out.println("Default constructor in }
Parent CLass");
} public Person(String name) {
public A(int a) System.out.println("Parameterized
{ constructor in Person: " + name);
System.out.println("Paremeterized }
}
constructor in Base CLass "+a);
} // Child class
} class Student extends Person {
class B extends A public Student() {
{ super(); // Calls default constructor of
public B() Person
{ System.out.println("Default constructor in
Student");
super();
}
System.out.println("Default constructor in
Derived CLass"); public Student(String name, int rollNo) {
} super(name); // Calls parameterized
public B(int a) constructor of Person
{ System.out.println("Parameterized
constructor in Student: Roll No " + rollNo);
super(10);
}
System.out.println("Paremeterized }
constructor in Derived CLass "+a);
} // Main class
} public class TestStudent {
public static void main(String[] args) {
13
class Main { Student s1 = new Student();
public static void main(String[] args) { Student s2 = new Student("Rutuja", 101);
B obj1=new B(); }
}
B obj=new B(5);
}
}
Output:
Output: Default constructor in Person
Default constructor in Parent CLass Default constructor in Student
Default constructor in Derived CLass Parameterized constructor in Person: Rutuja
Paremeterized constructor in Base CLass 10 Parameterized constructor in Student: Roll No
Parameterized constructor in Derived CLass 5 101
● The method in the subclass must have the same name as in the superclass.
● It must have the same return type and same parameter list.
● The subclass method must be accessible (same or higher visibility).
● The method in the superclass should not be final, static, or private.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
14
Key characteristics of method overriding:
● Inheritance:
Method overriding can only occur within an inheritance hierarchy, where a subclass
inherits methods from a superclass.
● Same Signature:
The overriding method in the subclass must have the exact same name, return type, and
parameter list (signature) as the method in the superclass it is overriding.
● Specific Implementation:
The purpose of overriding is to provide a specialized or different implementation of the
inherited method within the subclass, tailoring its behavior to the specific needs of the
child class.
● Runtime Polymorphism:
When a method is overridden, the version of the method executed is determined at
runtime based on the actual type of the object, not the declared type of the reference
variable. This is known as dynamic method dispatch.
● Restrictions:
Certain methods, such as final, static, or private methods in some languages (like Java),
cannot be overridden. Constructors also cannot be overridden.
● Example:
Example 1 Example 2
// Parent class // Parent class
class Vehicle { class Animal {
void start() { void sound() {
System.out.println("Vehicle is System.out.println("Animal makes a
starting"); sound");
} }
} }
15
reference, child object a.sound(); // Output: Dog
v.start(); // Output: Car is barks
starting with a key }
} }
}
Output: Output:
Car is starting with a key Dog barks
● An abstract class is a class that cannot be instantiated (you can't create objects of it).
● It is meant to be extended by other classes.
● It may contain abstract methods (without body) and concrete methods (with body).
● Abstract classes are used when you want to define a common structure or template for all
subclasses, but leave some methods to be implemented by the child classes.
Syntax:
abstract class ClassName {
// Concrete method
void regularMethod() {
System.out.println("This is a regular method.");
}
// Abstract method (no body)
abstract void abstractMethod();
}
3.Benefits
1. Encapsulation of Common Behavior
● Abstract classes allow you to define shared methods (like playmusic()) that all
subclasses can inherit.
● Promotes code reuse and avoids duplication.
16
2. . Enforcing a Contract
● Abstract methods (like drive()) must be implemented by subclasses.
● This ensures a consistent interface across different implementations.
3. Polymorphism Support
● You can use abstract class references to point to subclass objects.
● Enables flexible and dynamic method calls (Car obj = new Fortuner();).
4. Partial Implementation
● Unlike interfaces, abstract classes can provide some implementation.
● Useful when you want to offer default behavior while still requiring customization.
5. Improved Code Organization
● Helps in structuring large applications by grouping related classes under a common
abstract parent.
● Makes the codebase easier to understand and maintain.
6. Foundation for Inheritance
● Abstract classes serve as a base class for other classes.
● Encourages a logical hierarchy and promotes object-oriented design principles.
Example:
abstract class Car Output:
{ Can Drive...
public abstract void drive(); Play Music
void playmusic()
{
Car is an abstract class.
System.out.println("Play Music");
}
drive() is abstract → no body, must be
}
overridden.
class Fortuner extends Car playmusic() is a regular method →
{ already defined.
public void drive() Fortuner is a subclass of Car.
{ It implements the abstract method drive().
System.out.println("Can Drive...");
}
}
class Main {
public static void main(String[] args) {
Car obj=new Fortuner();
obj.drive();
obj.playmusic();
}
}
1.6 Polymorphism:
★ Introduction:
17
○ 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.
● 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.
Example:Consider a person who plays different roles in life, like a father, a husband, and
an employee. Each of these roles defines different behaviors of the person depending on
the object calling it.
Output
18
I am a father.
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.
1. Compile-Time Polymorphism
19
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.But Java doesn't support the Operator Overloading.
Method Overloading
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.
20
Explanation: The Multiply method is overloaded with different parameter types. The compiler
picks the correct method during compile time based on the arguments.
2. Runtime Polymorphism
Method Overriding
Example: This program demonstrates method overriding in Java, where the Print() method is
redefined in the subclasses (subclass1 and subclass2) to provide specific implementations.
21
a = new subclass2();
// Method a.Print();
void Print() { }
System.out.println("subclass1"); }
} Output
} subclass1
// Class 3 subclass2
// Helper class
class subclass2 extends Parent {
Explanation: In the above example, when an
// Method object of a child class is created, then the
void Print() {
System.out.println("subclass2");
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
Disadvantages of Polymorphism
❖ Software Reuse
22
Software reuse is the practice of designing components so they can be applied in multiple
scenarios.
❖ Software Efficiency
● Mechanism: Use streamlined logic, minimal redundancy, and smart resource handling.
● Purpose: Ensures faster execution, better responsiveness, and lower system load.
❖ Polymorphism
23