Inheritance, polymorphism, abstraction, and method overriding are core pillars of Object-Oriented Programming (OOP). These concepts allow Java developers to write reusable, flexible, and scalable code. By using these features, applications become easier to extend, maintain, and adapt to changing requirements. This module focuses on how classes interact with each other using inheritance and polymorphism.
Inheritance is a mechanism in which one class acquires the properties and behaviors of another class. The class that is inherited from is called the parent (superclass), and the class that inherits is called the child (subclass).
class ChildClass extends ParentClass {
// members
}
In single inheritance, a child class inherits from one parent class.
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
void bark() {
System.out.println("Dog is barking");
}
}
In multilevel inheritance, a class is derived from another derived class.
class Vehicle {
void start() {
System.out.println("Vehicle starts");
}
}
class Car extends Vehicle {
void drive() {
System.out.println("Car is driving");
}
}
class ElectricCar extends Car {
void charge() {
System.out.println("Electric car is charging");
}
}
In hierarchical inheritance, multiple child classes inherit from one parent class.
class Shape {
void draw() {
System.out.println("Drawing shape");
}
}
class Circle extends Shape {
void drawCircle() {
System.out.println("Drawing circle");
}
}
class Rectangle extends Shape {
void drawRectangle() {
System.out.println("Drawing rectangle");
}
}
Java does not support multiple inheritance with classes to avoid ambiguity (diamond problem).
The super keyword is used to refer to the immediate parent class object. It is mainly used to access parent class variables, methods, and constructors.
superclass Parent {
int value = 100;
}
class Child extends Parent {
int value = 200;
void display() {
System.out.println(super.value);
}
}
super.value accesses the parent class variable.
Method overriding occurs when a subclass provides a specific implementation of a method that is already defined in its parent class.
class Bank {
int getRateOfInterest() {
return 5;
}
}
class SBI extends Bank {
int getRateOfInterest() {
return 7;
}
}
Polymorphism means “many forms”. It allows the same method or object to behave differently in different situations.
Achieved using method overloading. The method call is resolved at compile time.
class MathUtil {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
Achieved using method overriding and dynamic method dispatch. The method call is resolved at runtime.
class Animal {
void sound() {
System.out.println("Animal makes sound");
}
}
class Cat extends Animal {
void sound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Cat();
a.sound();
}
}
An abstract class is a class that cannot be instantiated and may contain abstract methods.
An abstract method has no implementation and must be implemented by the subclass.
abstract class ClassName {
abstract void methodName();
}
abstract class Vehicle {
abstract void start();
}
class Bike extends Vehicle {
void start() {
System.out.println("Bike starts with kick");
}
}
The final keyword is used to restrict modification.
finalValue cannot be changed.
final int MAX = 100;
Cannot be overridden.
class Parent {
final void show() {
System.out.println("Final method");
}
}
Cannot be inherited.
final class Utility {
void display() {
System.out.println("Utility class");
}
}
java
// Parent class
abstract class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
// Abstract method
public abstract void makeSound();
// Concrete method
public void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class
class Dog extends Animal {
private String breed;
public Dog(String name, String breed) {
super(name); // Call parent constructor
this.breed = breed;
}
// Implementing abstract method
@Override
public void makeSound() {
System.out.println(name + " barks: Woof! Woof!");
}
// Overriding parent method
@Override
public void sleep() {
System.out.println(name + " the " + breed + " is sleeping peacefully");
}
public void fetch() {
System.out.println(name + " is fetching the ball");
}
}
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " meows: Meow! Meow!");
}
}
public class InheritanceDemo {
public static void main(String[] args) {
// Polymorphism
Animal myDog = new Dog("Buddy", "Golden Retriever");
Animal myCat = new Cat("Whiskers");
myDog.makeSound(); // Runtime polymorphism
myDog.sleep();
myCat.makeSound();
myCat.sleep();
// Downcasting
if (myDog instanceof Dog) {
Dog d = (Dog) myDog;
d.fetch();
}
}
}