Inheritance in Java
Sharing behavior between classes with extends, method overriding, and the role of super.
2 min read
Inheritance lets one class reuse and extend the fields and methods of another, modeling an "is-a" relationship: a Dog is an Animal, a SavingsAccount is a BankAccount. Instead of duplicating shared behavior across similar classes, you define it once in a parent and let children inherit it.
extends
public class Animal {
String name;
public Animal(String name) {
this.name = name;
}
void eat() {
System.out.println(name + " is eating.");
}
}
public class Dog extends Animal {
public Dog(String name) {
super(name); // calls Animal's constructor
}
void bark() {
System.out.println(name + " says Woof!");
}
}Dog rex = new Dog("Rex");
rex.eat(); // inherited from Animal: "Rex is eating."
rex.bark(); // defined on Dog: "Rex says Woof!"Dog is the subclass (or child class); Animal is the superclass (or parent class). Dog automatically gets Animal's name field and eat() method, on top of anything it defines itself. Java only allows single inheritance for classes — a class can extend exactly one superclass, though it can implement multiple interfaces (next lesson).
super
super(...) calls the parent class's constructor and must be the first statement in a subclass constructor, if used. super.methodName() calls the parent's version of a method, useful when overriding a method but still wanting the original behavior as part of it.
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
void eat() {
super.eat(); // run Animal's eat() first
System.out.println(name + " finishes the bowl quickly.");
}
}Method overriding
A subclass can override an inherited method to provide its own implementation, using the same name, parameters, and return type. The @Override annotation isn't required, but it's strongly recommended — it tells the compiler to verify you're actually overriding something, catching typos that would otherwise silently create an unrelated new method instead.
public class Animal {
void makeSound() {
System.out.println("Some generic animal sound");
}
}
public class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow");
}
}Polymorphism
Because a Cat is an Animal, an Animal-typed variable can hold a Cat object, and calling an overridden method on it runs the Cat version — this is runtime polymorphism, resolved based on the object's actual type, not the variable's declared type:
Animal pet = new Cat();
pet.makeSound(); // "Meow" -- Cat's override runs, even though the variable is typed AnimalThis is what lets you write code against a general Animal type while still getting each specific subclass's real behavior — the foundation for writing flexible, extensible object-oriented Java.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.