Inheritance

Inheritance

A school program needs reliable data and clear rules. Inheritance creates a subtype that receives accessible behavior from its superclass. A Graduate can use a general Student behavior and add its own capability.

  1. Understand

    Inheritance creates a subtype that receives accessible behavior from its superclass.

  2. Apply

    Trace the Java example, predict its output and explain the result before running it.

  3. Avoid mistakes

    Use inheritance for a meaningful is-a relationship. Private superclass fields are not directly accessible in subclass code.

Inheritance in Java

Inheritance allows a class to inherit fields and methods from another class, promoting code reuse and logical hierarchy. In simple terms, inheritance lets us create new classes based on existing ones.

Types of Inheritance in Java

Java supports the following types of inheritance:

  • Single Inheritance
  • Multilevel Inheritance
  • Hierarchical Inheritance

Note: Java does not support multiple inheritance with classes to avoid ambiguity. However, it can be achieved using interfaces.

Syntax of Inheritance

This syntax shows how a class inherits from another using the extends keyword. The Child class gains access to all the fields and methods of the Parent class, and can also define its own.

class Parent {
    // fields and methods
}

class Child extends Parent {
    // additional fields and methods
}

Single Inheritance

This example shows how a subclass inherits methods from a single superclass. The Dog class inherits the sound() method from Animal, and also defines its own method bark(). In the main method, both inherited and own methods are accessible through the Dog object.

  class Animal {
    void sound() {
        System.out.println("Animals make sounds");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.sound();  // inherited method
        d.bark();   // own method
    }
}
Animals make sounds
Dog barks

Multilevel Inheritance

This example demonstrates multilevel inheritance, where a class inherits from a derived class, forming a chain. The class Puppy inherits from Dog, which in turn inherits from Animal. As a result, Puppy has access to methods of both Dog and Animal.

class Animal {
    void eat() {
        System.out.println("Eating...");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Barking...");
    }
}

class Puppy extends Dog {
    void weep() {
        System.out.println("Weeping...");
    }
}

public class Main {
    public static void main(String[] args) {
        Puppy p = new Puppy();
        p.eat();
        p.bark();
        p.weep();
    }
}
Eating...
Barking...
Weeping...

Hierarchical Inheritance

This example demonstrates hierarchical inheritance where multiple classes (Dog and Cat) inherit from a single base class (Animal). Both subclasses reuse the breathe() method from Animal, while also having their own specific methods (bark() and meow()).

class Animal {
    void breathe() {
        System.out.println("Breathing...");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Barking...");
    }
}

class Cat extends Animal {
    void meow() {
        System.out.println("Meowing...");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog();
        d.breathe();
        d.bark();

        Cat c = new Cat();
        c.breathe();
        c.meow();
    }
}
Breathing...
Barking...
Breathing...
Meowing...

Method Overriding in Inheritance

When a subclass provides its own implementation of a method that is already defined in its parent class, it is called method overriding. This allows the subclass to define behavior specific to its type.

The @Override annotation is used to indicate that a method is being overridden.

In the example, the Dog class overrides the sound() method of the Animal class. When sound() is called on an Animal reference pointing to a Dog object, the overridden method in Dog executes, demonstrating runtime polymorphism.

class Animal {
    void sound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal a = new Dog();
        a.sound();  // calls overridden method
    }
}
Dog barks

Why Use Inheritance?

  • To avoid code duplication
  • To establish a natural hierarchy between classes
  • To allow for method overriding and polymorphism
  • To enhance maintainability and scalability

Important Points to Remember

  • Java only supports single inheritance through classes.
  • Use super to call parent class methods or constructors.
  • Overridden methods in subclasses are called based on the actual object type at runtime (polymorphism).
  • Constructors are not inherited but the parent constructor can be called using super().

Important boundaries and mistakes

Use inheritance for a meaningful is-a relationship. Private superclass fields are not directly accessible in subclass code.

Try the school example

Before running this Java program, write down each line you expect to see. Identify the value, branch, object or exception responsible for each line. Then explain whether the following assumption is valid: Use inheritance for a meaningful is-a relationship.

Java 17 · Main.java · complete practice program

public class Main  {
  interface Named  {
    String label();
  }
  static class Graduate extends Student  {
    Graduate()  {
      super("Diya");
    }
  }
  static class Student implements Named  {
    static String school = "River School";
    String name;
    Student(String name)  {
      this.name = name;
    }
    public String label()  {
      return name;
    }
    String role()  {
      return "Student";
    }
  }
  public static void main(String[] args)  {
    System.out.println(new Graduate().role());
  }
}

Worked answer and reasoning

Java 17 · Main.java · source repeated for this answer

public class Main  {
  interface Named  {
    String label();
  }
  static class Graduate extends Student  {
    Graduate()  {
      super("Diya");
    }
  }
  static class Student implements Named  {
    static String school = "River School";
    String name;
    Student(String name)  {
      this.name = name;
    }
    public String label()  {
      return name;
    }
    String role()  {
      return "Student";
    }
  }
  public static void main(String[] args)  {
    System.out.println(new Graduate().role());
  }
}

Expected output

Student

Inheritance creates a subtype that receives accessible behavior from its superclass. A Graduate can use a general Student behavior and add its own capability.

Use inheritance for a meaningful is-a relationship. Private superclass fields are not directly accessible in subclass code.

Run with javac Main.java, then java Main. The declaration inside Main keeps the helper type available to this standalone example.

Check your understanding

For the complete practice program in this lesson, which output is expected on Java 17?
Choose one answer. You can try again.

Answer and explanation

Student

Inheritance creates a subtype that receives accessible behavior from its superclass. A Graduate can use a general Student behavior and add its own capability. Use inheritance for a meaningful is-a relationship. Private superclass fields are not directly accessible in subclass code.

What to remember

Inheritance creates a subtype that receives accessible behavior from its superclass. A Graduate can use a general Student behavior and add its own capability. Use inheritance for a meaningful is-a relationship. Private superclass fields are not directly accessible in subclass code.

Related explanations: Java Variables, Java If Statement - Syntax and Examples, Java Class - Blueprint of Objects, Exceptions in Java Introduction.

Supporting documentation: Official Java learning guide and Java 17 language specification.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Method Overriding →