Inheritance models a substitutable is-a relationship. Use overriding and super deliberately, preserve base-class contracts, and prefer composition when behavior sharing does not imply substitutability.
Before using inheritance, ask whether the child can truly stand in for the parent. If substituting the child would surprise callers, the relationship is weak and composition may create a simpler, safer design.
The extends keyword creates a subclass. The super keyword can call parent constructors and parent methods.
class Vehicle {
private String brand;
Vehicle(String brand) {
this.brand = brand;
}
void start() {
System.out.println(brand + " starting");
}
}
class Car extends Vehicle {
Car(String brand) {
super(brand);
}
void openTrunk() {
System.out.println("Trunk opened");
}
}
Overriding lets a subclass provide a new implementation for an inherited method. Use @Override so the compiler catches signature mistakes.
class Animal {
String sound() {
return "Some sound";
}
}
class Dog extends Animal {
@Override
String sound() {
return "Bark";
}
}
final prevents inheritance or overriding. protected allows access in subclasses and same-package classes. Use protected carefully because it exposes internals to subclasses.
Inheritance is powerful when a child really is a specialized form of the parent. If the relationship is only code reuse, composition is often cleaner because it avoids fragile parent-child coupling.
The compiler then catches spelling and signature mistakes.
No. A subclass constructor calls a superclass constructor but does not inherit it.
Use composition when the relationship is "uses" or "has," not truly "is a."
Practice, interview questions, and compiler links for Core Java.
Finish the concept here, then reinforce it with hands-on coding, interview prep, or a tool that matches the topic.
Explore 500+ free tutorials across 20+ languages and frameworks.
Fresh tutorials, interview guides, and coding practice in your inbox.