Inheritance

Basic Java
≈ 3 min read

Shared behavior without duplication

Imagine several classes that have a common foundation. For example, a dog and a cat are different animals, but both may need a name and an eat() action. Instead of repeating the same code in every class, you can move the common part into a parent class and make the more specific class inherit from it.

class Animal {
    private final String name;

    Animal(String name) {
        this.name = name;
    }

    String name() {
        return name;
    }

    void eat() {
        System.out.println(name + " ест");
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
    }

    void bark() {
        System.out.println(name() + " лает");
    }
}

The extends keyword says that Dog inherits from Animal. That means a Dog object has not only its own bark() method, but also the behavior available to it from the parent class:

Dog dog = new Dog("Рекс");
dog.eat();
dog.bark();

Inheritance is useful to read as an “is-a” relationship: Dog is an Animal, while also adding more specific capabilities. The parent class is commonly called a superclass, and the inheriting class a subclass.

What the subclass gets

A subclass can use the fields and methods of the parent class that are accessible to it and can add its own. Access modifiers still apply, however. For example, the name field in the example is declared private, so Dog cannot access it directly. Instead, it uses the accessible name() method.

Constructors are not inherited. When an object of the child class is created, the parent part of that object must also be initialized. In the example, the Dog constructor passes the name to the Animal constructor through super(name).

Dog(String name) {
    super(name);
}

If the parent class has a suitable no-argument constructor, an explicit super() call often does not need to be written. If no such constructor exists, you need to call an appropriate parent constructor yourself.

A class has only one direct parent

A regular Java class can directly inherit from only one other class. For example, class Dog extends Animal is valid, but you cannot list two classes after extends. The chain itself can still be longer: one class can inherit from another, which inherits from a third, and so on.

Inheritance should describe meaning

Inheritance should not be used only because you want to reuse a few lines of code. It works well when the child class really is a more specific version of the parent class. A Dog is an Animal, so that relationship is natural.

Check the “is-a” relationship. If the sentence “A is a B” sounds strange, inheritance probably does not describe the relationship between the classes well. In that case, it is better not to connect shared functionality through an artificial hierarchy.

So inheritance lets you move the common part into a parent class and keep only what makes the child class more specific inside the child itself. In the next topic, this relationship between parent and child classes will become the foundation for another important OOP capability.