OOP Intermediate
Inheritance
Extending Classes
You have Employee, Manager, and Developer classes. They share fields like name and salary. Instead of duplicating code, inheritance lets Manager and Developer extend Employee, inheriting its fields and methods while adding their own.
Basic inheritance
Create a subclass that extends a parent class.
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
// Basic Inheritance
public class Basic {
public static void main(String[] args) {
System.out.println("=== Basic Inheritance ===\n");
// Create a Dog object
Dog dog = new Dog();
String dogName = ;
dog.name = dogName;
// Dog has its own method
dog.bark();
// Dog inherits from Animal
dog.eat();
dog.sleep();
System.out.println("\n=== Accessing Inherited Fields ===");
// Inherited field
System.out.println("Dog's name: " + dog.name);
System.out.println("Dog's age: " + dog.age);
System.out.println("\n=== Cat Example ===");
Cat cat = new Cat();
String catName = ;
cat.name = catName;
cat.meow();
cat.eat(); // Inherited
cat.sleep(); // Inherited
}
}
// Parent class (superclass)
class Animal {
String name;
int age;
void eat() {
System.out.println(name + " is eating");
}
void sleep() {
System.out.println(name + " is sleeping");
}
}
// Child class (subclass)
class Dog extends Animal {
// Dog-specific method
void bark() {
System.out.println(name + " says: Woof!");
}
}
// Another child class
class Cat extends Animal {
void meow() {
System.out.println(name + " says: Meow!");
}
}
class Child extends Parent inherits all non-private members from Parent.
Call parent constructor
Initialize parent class fields with super().
// Calling Parent Constructor with super()
public class SuperConstructor {
public static void main(String[] args) {
System.out.println("=== super() Constructor Call ===\n");
// Create Employee
Employee emp = new Employee("Alice", 30);
emp.displayInfo();
System.out.println("\n=== Manager (extends Employee) ===");
// Create Manager
Manager mgr = new Manager("Bob", 45, "Engineering");
mgr.displayInfo();
System.out.println("\n=== Developer (extends Employee) ===");
Developer dev = new Developer("Carol", 28, "Java");
dev.displayInfo();
System.out.println("\n=== Constructor Call Order ===");
System.out.println("Creating new Manager...");
Manager mgr2 = new Manager("Dan", 35, "Sales");
}
}
// Parent class
class Person {
String name;
int age;
Person(String name, int age) {
System.out.println(" Person constructor called");
this.name = name;
this.age = age;
}
}
// Child class
class Employee extends Person {
int employeeId;
static int nextId = 1000;
Employee(String name, int age) {
super(name, age);
System.out.println(" Employee constructor called");
this.employeeId = nextId++;
}
void displayInfo() {
System.out.println("Employee: " + name + ", Age: " + age + ", ID: " + employeeId);
}
}
// Grandchild class
class Manager extends Employee {
String department;
Manager(String name, int age, String department) {
super(name, age);
System.out.println(" Manager constructor called");
this.department = department;
}
@Override
void displayInfo() {
System.out.println("Manager: " + name + ", Age: " + age +
", ID: " + employeeId + ", Dept: " + department);
}
}
class Developer extends Employee {
String language;
Developer(String name, int age, String language) {
super(name, age); // Calls Employee constructor
this.language = language;
}
@Override
void displayInfo() {
System.out.println("Developer: " + name + ", Age: " + age +
", ID: " + employeeId + ", Lang: " + language);
}
}
super(args) calls parent constructor. Must be first statement.
Override parent methods
Replace parent behavior in subclass.
// Method Overriding
public class MethodOverride {
public static void main(String[] args) {
System.out.println("=== Method Overriding ===\n");
Animal animal = new Animal("Generic Animal");
animal.makeSound();
animal.move();
System.out.println("\n=== Dog Override ===");
Dog dog = new Dog("Buddy");
dog.makeSound(); // Overridden
dog.move(); // Inherited (not overridden)
System.out.println("\n=== Bird Override ===");
Bird bird = new Bird("Tweety");
bird.makeSound(); // Overridden
bird.move(); // Overridden
System.out.println("\n=== Calling Parent Method with super ===");
Cat cat = new Cat("Whiskers");
cat.makeSound();
}
}
class Animal {
String name;
Animal(String name) {
this.name = name;
}
void makeSound() {
System.out.println(name + " makes a sound");
}
void move() {
System.out.println(name + " moves around");
}
}
class Dog extends Animal {
Dog(String name) {
super(name);
}
@Override
void makeSound() {
System.out.println(name + " barks: Woof! Woof!");
}
// move() is inherited as-is
}
class Bird extends Animal {
Bird(String name) {
super(name);
}
@Override
void makeSound() {
System.out.println(name + " chirps: Tweet! Tweet!");
}
@Override
void move() {
System.out.println(name + " flies through the air");
}
}
class Cat extends Animal {
Cat(String name) {
super(name);
}
@Override
void makeSound() {
super.makeSound();
System.out.println(name + " also meows: Meow!");
}
}
Same signature in subclass replaces parent method. Use @Override annotation.
Protected access
Share members with subclasses but not the world.
// Protected Access Modifier
public class Protected {
public static void main(String[] args) {
System.out.println("=== Protected Access ===\n");
// Create BankAccount
BankAccount account = new BankAccount("Alice", 1000);
account.displayInfo();
System.out.println("\n=== SavingsAccount (child) ===");
SavingsAccount savings = new SavingsAccount("Bob", 5000, 0.03);
savings.displayInfo();
savings.addInterest();
savings.displayInfo();
System.out.println("\n=== Access Levels Demo ===");
System.out.println("""
Access Modifiers in Inheritance:
| Modifier | Same Class | Subclass | Other Classes |
|------------|------------|----------|---------------|
| private | Yes | No | No |
| (default) | Yes | Yes* | Yes* |
| protected | Yes | Yes | No |
| public | Yes | Yes | Yes |
* Same package only
""");
}
}
class BankAccount {
private String accountNumber;
protected String ownerName;
protected double balance;
public BankAccount(String owner, double initialBalance) {
this.accountNumber = generateAccountNumber();
this.ownerName = owner;
this.balance = initialBalance;
}
private String generateAccountNumber() {
return "ACC" + System.currentTimeMillis() % 10000;
}
protected void updateBalance(double amount) {
this.balance += amount;
System.out.println("Balance updated by: " + amount);
}
public void displayInfo() {
System.out.println("Account: " + accountNumber);
System.out.println("Owner: " + ownerName);
System.out.println("Balance: $" + balance);
}
}
class SavingsAccount extends BankAccount {
private double interestRate;
public SavingsAccount(String owner, double initialBalance, double rate) {
super(owner, initialBalance);
this.interestRate = rate;
}
public void addInterest() {
// Can access protected field 'balance'
double interest = balance * interestRate;
// Can call protected method
updateBalance(interest);
// Can access protected field 'ownerName'
System.out.println("Interest added for " + ownerName);
// Cannot access private 'accountNumber'!
// System.out.println(accountNumber); // ERROR!
}
}
protected is visible in subclasses and same package. More open than private.
Multi-level inheritance
Chain of inheritance: grandparent → parent → child.
// Multi-Level Inheritance Chain
public class InheritanceChain {
public static void main(String[] args) {
System.out.println("=== Multi-Level Inheritance ===\n");
// Create SportsCar (3 levels deep)
SportsCar ferrari = new SportsCar("Ferrari", "488", 2023, 660);
ferrari.displayInfo();
System.out.println("\n--- Demonstrating Methods ---");
ferrari.start(); // From Vehicle
ferrari.accelerate(); // From Car
ferrari.boost(); // From SportsCar
ferrari.stop(); // From Vehicle
System.out.println("\n=== Inheritance Hierarchy ===");
System.out.println("""
Vehicle (grandparent)
↓
Car (parent)
↓
SportsCar (child)
SportsCar inherits from Car,
which inherits from Vehicle.
SportsCar has access to ALL
non-private members of both!
""");
System.out.println("=== Creating Different Levels ===\n");
Vehicle vehicle = new Vehicle("Generic");
vehicle.displayInfo();
vehicle.start();
System.out.println();
Car car = new Car("Toyota", "Camry", 2022);
car.displayInfo();
car.start();
car.accelerate();
}
}
// Level 1: Base class
class Vehicle {
protected String brand;
Vehicle(String brand) {
this.brand = brand;
}
void start() {
System.out.println(brand + ": Starting engine...");
}
void stop() {
System.out.println(brand + ": Stopping...");
}
void displayInfo() {
System.out.println("Brand: " + brand);
}
}
// Level 2: Extends Vehicle
class Car extends Vehicle {
protected String model;
protected int year;
Car(String brand, String model, int year) {
super(brand);
this.model = model;
this.year = year;
}
void accelerate() {
System.out.println(brand + " " + model + ": Accelerating...");
}
@Override
void displayInfo() {
super.displayInfo();
System.out.println("Model: " + model);
System.out.println("Year: " + year);
}
}
// Level 3: Extends Car
class SportsCar extends Car {
private int horsepower;
SportsCar(String brand, String model, int year, int hp) {
super(brand, model, year);
this.horsepower = hp;
}
void boost() {
System.out.println(brand + " " + model + ": BOOST! (+" + horsepower + " HP)");
}
@Override
void displayInfo() {
super.displayInfo(); // Calls Car's displayInfo
System.out.println("Horsepower: " + horsepower);
}
}
Child inherits from parent, which inherits from grandparent. Chain can be long.
Exercise: Practical.java
Build a complete class hierarchy with inheritance