Inheritance in Java: Learn extends, super, and Overriding with Runnable Examples
Follow one runnable Vehicle and ElectricCar program to see inherited methods, constructor order, super calls, runtime dispatch, common errors, and practice tasks.
KnowledgeGate Team
Exam prep & CS education

Inheritance is often reduced to the extends keyword, but the real challenge is predicting which state is available, which constructor runs, and which method body executes. In the Vehicle and ElectricCar program, one object carries superclass and subclass state while an overridden method is selected at runtime.
What Inheritance Means in Java
A superclass represents a general idea, while a subclass represents a specialised version. ElectricCar is a Vehicle passes the useful "is-a" test, so inheritance fits. ElectricCar has a Battery is a "has-a" relationship, which normally calls for composition instead.
The basic class declaration is:
class ElectricCar extends Vehicle { }Oracle's inheritance rules say that a class has one direct superclass, every class except Object ultimately descends from Object, and a subclass can reuse accessible fields and methods while adding or overriding behaviour. The language-independent model of objects, encapsulation, inheritance, and polymorphism is explained in OOP for CS teaching exams: classes, inheritance and polymorphism explained. The Vehicle and ElectricCar trace applies those ideas to Java-specific access, constructor, and dispatch rules.
Build the First Runnable Superclass and Subclass
Save this exact program as Main.java, then compile and run it.
class Vehicle {
private final String model;
private int speedKmph;
Vehicle(String model, int speedKmph) {
this.model = model;
this.speedKmph = speedKmph;
}
public void accelerate(int increase) {
speedKmph += increase;
}
public String status() {
return model + " at " + speedKmph + " km/h";
}
}
class ElectricCar extends Vehicle {
private int batteryPercent;
ElectricCar(String model, int speedKmph, int batteryPercent) {
super(model, speedKmph);
this.batteryPercent = batteryPercent;
}
public void useBattery(int points) {
batteryPercent -= points;
}
@Override
public String status() {
return super.status() + ", battery " + batteryPercent + "%";
}
}
public class Main {
public static void main(String[] args) {
ElectricCar car = new ElectricCar("Nexon EV", 40, 82);
car.accelerate(15);
car.useBattery(7);
Vehicle ref = car;
System.out.println(ref.status());
}
}Trace the numbers before looking at the output. speedKmph begins at 40; accelerate(15) makes it 40 + 15 = 55. batteryPercent begins at 82; useBattery(7) makes it 82 - 7 = 75. Therefore the exact output is:
Nexon EV at 55 km/h, battery 75%If you need a sequenced path through programming fundamentals, use the Coding & DSA category after you finish tracing this program.

What Is Inherited, and What super Does
car.accelerate(15) works because the public method is inherited. The representation stays controlled by Vehicle: ElectricCar cannot directly read its private speedKmph field. Following Oracle's access summary, remember this beginner-level map:
publicmembers are accessible wherever the class is visible.protectedmembers are available to subclasses, subject to Java's package rules.Package-private members are accessible to a subclass only when it is in the same package.
privatemembers are not inherited as subclass members and cannot be accessed directly there.
The Packages and Access Modifiers in Java: Visibility Rules with Runnable Examples tutorial works through the full four-context matrix and the cross-package protected receiver rule. For this inheritance trace, the narrower question is which Vehicle members ElectricCar can reuse or access.
Constructors are not inherited. For new ElectricCar("Nexon EV", 40, 82), the subclass constructor first calls super(model, speedKmph). The Vehicle part stores "Nexon EV" and 40, then the ElectricCar part stores 82.
If the explicit super(...) call were omitted, the compiler would try super(). That would fail because this Vehicle has no accessible no-argument constructor. In this program, super(...) selects the superclass constructor, while super.status() deliberately runs the superclass version of an overridden method.
The Constructors in Java: Types, Chaining and Runnable Examples tutorial develops default, overloaded, this(), and parent-constructor chains. Here, super(...) initializes the Vehicle state that the overridden status() method later reads.
Overriding and Runtime Method Selection
@Override asks the compiler to confirm that ElectricCar.status() matches an inherited instance method. Overriding keeps the same method signature and selects the implementation at runtime. Overloading uses a different parameter list and is resolved at compile time.
Now trace Vehicle ref = car. The reference type is Vehicle, but the actual object is ElectricCar. Calling ref.status() therefore runs ElectricCar.status(). That method calls Vehicle.status() through super, gets Nexon EV at 55 km/h, then appends the battery state 75%.
Runtime dispatch applies to overridden instance methods. Fields and static methods are hidden, not dynamically overridden, so do not use the same prediction rule for them.

Types of Inheritance Java Supports
Java class hierarchies can take three common shapes:
Single:
ElectricCar extends Vehicle.Multilevel:
SportsEV extends ElectricCar, which already extendsVehicle.Hierarchical:
ElectricCarandDieselCarboth extendVehicle.
Each class still has one direct superclass. This declaration is invalid and causes a compile-time error:
class AmphibiousCar extends Car, Boat { }The important qualification is that a class can implement multiple interfaces:
class FleetEV extends ElectricCar implements Chargeable, Trackable { }This is multiple inheritance of type. It does not create two copies of superclass state or inherit constructors from two classes.
Common Inheritance Errors and Their Fixes
Constructor failure
If Vehicle provides only Vehicle(String, int), then class ElectricCar extends Vehicle { ElectricCar() {} } fails because its implicit super() cannot resolve. Call an available constructor explicitly, such as super("Nexon EV", 40).
Access and override failures
Writing speedKmph += 15 inside ElectricCar fails because the field is private. Reuse accelerate(15) or provide a deliberate accessor. A misspelled public String stats() is a new method, not an override. Adding @Override makes the compiler expose that mistake.
Unsafe downcast
This code compiles but throws ClassCastException at runtime:
Vehicle plain = new Vehicle("Bus", 30);
ElectricCar ev = (ElectricCar) plain;Guard a cast with plain instanceof ElectricCar. If a design needs repeated downcasts, reconsider whether the abstraction is doing useful work.
How Exams and Interviews Test Inheritance
Typical tasks ask you to predict output, separate compile-time and runtime errors, trace constructor calls, distinguish overriding from overloading or hiding, and judge whether a cast is safe. Oracle's official Java inheritance tutorial documents these stable fundamentals. Oracle labels that tutorial as JDK 8-era material, so use it for inheritance rules, not current-release claims.
Test the rules with these exercises:
Change
accelerate(15)toaccelerate(25). Speed becomes40 + 25 = 65, while battery remains82 - 7 = 75. Answer:Nexon EV at 65 km/h, battery 75%.Replace
Vehicle ref = carwithObject ref = car.ref.status()does not compile becauseObjectdoes not declarestatus(), even though the actual object is anElectricCar.Evaluate
new Vehicle("Bus", 30) instanceof ElectricCar. The answer isfalsebecause that object is aVehicle, not anElectricCar.
For a design exercise, create DeliveryEV extends ElectricCar with loadKg = 120, construct it as new DeliveryEV("E-Transit", 35, 76), then call accelerate(10) and useBattery(8). The values become 35 + 10 = 45 and 76 - 8 = 68. Override status() using super.status() so the result is exactly E-Transit at 45 km/h, battery 68%, load 120 kg.
Short Version and the Next Step
extendscreates the class relationship.Accessible members are inherited.
Constructors run in a chain but are not inherited.
superreaches superclass construction or behaviour.Overridden instance methods dispatch by the actual object type.
Continue with Java Programming for a structured language sequence. Use Data Structures and Algorithms Using Java after classes, inheritance, and collections feel comfortable and you are ready to apply them to data structures and placement problems.
Now rerun Main, complete the three prediction exercises, and implement DeliveryEV without looking back at the answer string.
Keep learning
TreeMap and SortedMap in Java: Ordering, Range Views and Worked Examples
Learn how Java's TreeMap orders keys, answers floor and ceiling queries, exposes live range views, and handles comparator collisions through worked examples.
HashSet and TreeSet in Java: Runnable Examples and Key Differences
Learn how Java sets handle duplicates, ordering, navigation and custom objects through deterministic examples you can run and modify.
Java Garbage Collection Tutorial: Reachability, Leaks and Runnable Examples
Trace three connected objects, find exactly when each becomes eligible for collection, and repair a cache that keeps byte arrays reachable.
Java Memory Model Tutorial: Happens-Before, volatile and Safe Publication
Learn the Java Memory Model through exact start/join, volatile, synchronized, final-field and AtomicInteger examples, with clear happens-before guarantees.





