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.java
// 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.

extends Inherit from a class: `class Dog extends Animal`. Dog gets Animal's fields and methods.

Call parent constructor

Initialize parent class fields with super().

SuperConstructor.java
// 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.

super Reference to parent class. `super()` calls constructor, `super.method()` calls method.

Override parent methods

Replace parent behavior in subclass.

MethodOverride.java
// 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.

override Subclass provides its own version of parent method. Same name and parameters.

Protected access

Share members with subclasses but not the world.

Protected.java
// 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.

protected Access modifier: visible to subclasses and same package.

Multi-level inheritance

Chain of inheritance: grandparent → parent → child.

InheritanceChain.java
// 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