Inheritance
What you'll learn:
- declare a subclass with
extendsand call the parent's constructor withsuper(…); - predict whose method the call
a.sound()runs, and tell overriding from overloading; - explain what the words
abstractandfinaldo for a class and a method; - cast a reference to a subclass type and check an object's type with
instanceof.
Picture a TV and its remote. The remote has two buttons: "On" and "Volume". A year later the company releases a new model. It does everything the old one did, and it also records shows. The new model is not designed from scratch: the engineers take the old one and add one feature.
That is why the old remote works with the new TV too. The new model understands every one of its buttons: everything the old model had is still there.
Inheritance in Java works the same way: a new class gets the fields and methods of an existing class and adds its own.
Why is this useful? Say a program has dogs and cats, and both of them eat. Without inheritance, the eat method would have to be written in both classes, and a bug found in it would have to be fixed twice. With inheritance, the shared part is written once, in a class Animal:
public class Main {
public static void main(String[] args) {
Dog d = new Dog();
d.eat(); // eats
d.bark(); // Woof
}
}
class Animal {
void eat() { System.out.println("eats"); }
}
class Dog extends Animal {
void bark() { System.out.println("Woof"); }
}Let's walk through the program step by step:
- The class
Animaldescribes what every animal can do: the methodeat. Its body is written on one line here to keep the example short. class Dog extends Animaldeclares the classDoga subclass ofAnimal. The wordextendsmeans what it says:DogextendsAnimal.Dogitself contains only the methodbark.new Dog()builds a dog, andd.eat()printseats: the dog got this method fromAnimal.d.bark()printsWoof: this isDog's own method.
Parent and child
Inheritance is a way to declare a new class based on an existing one: the new class gets the fields and methods of the old one. The class being inherited from is called the superclass, or parent, and the new class the subclass, or child. Here Animal is the superclass and Dog the subclass.
Inheritance describes an "is a" relationship: a dog is an animal. That is why everything an Animal can do, a Dog can do too. The reverse is not true: Animal has no bark method.
What a subclass gets and what it does not:
- it gets the parent's fields and methods: a
Dogobject uses them as its own; - the parent's
privatefields and methods are visible only inside the parent: ifDogtouches theprivatefieldnameofAnimal, the compiler answersname has private access in Animal; - constructors are not inherited: every class has its own.
The parent's constructor: super(…)
A dog is an animal plus something of its own. So when a Dog object is built, the part that Animal describes has to be set up first. If Animal has a constructor with a parameter, the subclass calls it with the word super:
public class Main {
public static void main(String[] args) {
Dog d = new Dog("Rex");
System.out.println(d.name); // Rex
}
}
class Animal {
String name;
Animal(String name) { this.name = name; }
}
class Dog extends Animal {
Dog(String name) { super(name); }
}Step by step:
new Dog("Rex")calls theDogconstructor with the argument"Rex".- The first statement of that constructor,
super(name), calls theAnimalconstructor and passes it"Rex". - The
Animalconstructor stores the name in the fieldname, and control returns to theDogconstructor. d.nameprintsRex: the field is declared inAnimaland filled in throughsuper.
These are the rules for super(…):
- it is written as the first statement of a constructor, like
this(…); Java 25 allows some statements before it, but the course's code also compiles on Java 21; - if you do not write
super(…), the compiler insertssuper()at the start of the constructor, a call to the parent's constructor with no arguments; - so the parent's constructor always finishes before the subclass code after
super(…)runs.
Interviewers often ask about the order in which constructors run. The answer: top down, from the most distant parent to the subclass.
One parent and the class Object
A Java class has exactly one parent: class Dog extends Animal, Pet does not compile. The chain can be long, though: a class Puppy extends Dog gets everything from both Dog and Animal.
And if you write no extends, the parent is the class Object. It sits at the root of all classes: every class is its subclass, directly or through a chain. That is why every object has the methods of Object, such as toString.
Here the TV picture is off. Engineers can build a new model from parts of two older ones, but a Java class always has one parent.
Common mistake
The parent needs an argument, and the subclass did not call super(…):
class Animal {
String name;
Animal(String name) { this.name = name; }
}
class Dog extends Animal {
Dog(String name) { } // ✗
}error: constructor Animal in class Animal cannot be applied to given types;The program does not compile. Since super(…) is missing, the compiler inserted super() with no arguments, and Animal has no such constructor: it has only the one that takes a String. It is the same message you get from new without the arguments a constructor needs. Call the parent's constructor yourself: Dog(String name) { super(name); }.
Key points
class Dog extends Animaldeclares a subclass:Doggets the fields and methods ofAnimaland adds its own.- The parent's
privatemembers are not visible to the subclass, and constructors are not inherited. super(…)calls the parent's constructor; without it the compiler insertssuper(), and the parent's constructor finishes before the subclass code runs.- A class has exactly one parent, and
Objectsits at the root of all classes.