Inheritance & Polymorphism
java1-4 built one class in isolation. Real programs build hierarchies — this chapter covers how, and where Java deliberately draws a harder line than C++ ever did.
extends & Single Inheritance
A Java class can extends exactly one other class. This is a hard rule, not a convention — where C++ allows a class to inherit from several base classes at once (the exact mechanism behind cpp3-1's diamond problem), Java simply never lets that ambiguity arise in the first place.
super — Reaching Into the Parent
super(...) calls the superclass's constructor and must be the first statement in a subclass constructor if written explicitly. super.methodName() calls the superclass's version of an overridden method from inside the override itself.
Method Overriding — Virtual by Default
A genuine, real difference from C++: every Java instance method is virtual by default — dynamically dispatched based on the object's actual runtime type — unless explicitly marked final, private, or static. cpp1-7's own material required the explicit virtual keyword in C++ for this exact behavior; Java simply never offers a non-virtual instance method as the default at all.
Why Single Inheritance of Classes
Java's restriction to one extends per class is a structural choice, not a limitation nobody thought to lift — it's the same underlying goal cpp3-1's own virtual-inheritance fix pursued for C++, achieved here by never allowing a class to inherit state from more than one place to begin with. Behavior from multiple sources is still possible in Java — through interfaces, covered next chapter — but state never comes from more than one superclass.
| Behavior | C++ (cpp1-7 / cpp3-1) | Java |
|---|---|---|
| Classes a class can inherit from | multiple, directly | exactly one (extends) |
| Diamond problem | possible — needs virtual inheritance to fix | structurally impossible for state |
| Virtual dispatch default | opt-in via the virtual keyword | on by default for every instance method |
| Multiple sources of behavior | multiple inheritance | interfaces (next chapter) |
@Override doesn't change runtime behavior — it asks the compiler to verify the method actually overrides something in a superclass, catching a typo'd method signature (which would otherwise silently become an unrelated overload) at compile time instead of leaving a hard-to-notice bug.
super(...) explicitly, Java inserts a no-argument super() call automatically. This silently works right up until the superclass has no no-argument constructor at all — at which point the subclass fails to compile until super(...) is written explicitly with matching arguments.
Coding Challenges
Write a Shape class with a protected name field and an area() method returning 0.0, then a Circle subclass that extends it, calls super() in its constructor, and overrides area() correctly using @Override.
📄 View solutionStore a Circle in a variable declared as type Shape, call area() on it, and explain in a comment why the Circle version runs even though the variable's declared type is Shape — referencing what makes this possible by default in Java but not in C++.
📄 View solutionWrite a superclass with only a constructor that takes an argument (no no-arg constructor), then write a subclass whose constructor forgets to call super(...) explicitly. Show the resulting compile error and explain why it happens.
📄 View solutionChapter 5 Quick Reference
- extends allows exactly one superclass — Java never permits multiple inheritance of state
- super(...) calls the superclass constructor; super.method() calls the superclass's version of an overridden method
- Every instance method is virtual/dynamically-dispatched by default — no virtual keyword needed, unlike C++'s opt-in model
- @Override doesn't change behavior — it makes the compiler verify a real override exists, catching typo'd overloads
- Single inheritance of classes is Java's structural answer to the diamond problem cpp3-1 covered for C++
- Next chapter: interfaces and abstract classes — Java's own way to get behavior from multiple sources