Reaching up to the parent, and locking a class down
super lets a subclass explicitly reach its parent's constructor or an overridden method. final, at the class or method level, is how you declare a piece of a design closed to further extension.
After this lesson
You should be able to
- Use super to call a parent constructor and a parent's overridden method.
- Explain the difference between private, protected, and public in an inheritance context.
- Explain what marking a class or method final prevents.
Access rules change meaning once inheritance exists
private, from the earlier lesson, is now too strict for one common case: a field only the class itself can see, not even its own subclasses. protected fixes that — visible to the class, every subclass, and other classes in the same package, but still hidden from unrelated code. Choosing protected over private is a real design decision: it is a promise to every future subclass that this field is part of the stable contract they can depend on.
super reaches past the current class to its immediate parent. super(args) inside a constructor calls the parent's constructor — you saw this already building Student's constructor. super.methodName() calls the parent's version of a method even when the current class has overridden it, useful when a subclass wants to add behaviour on top of the parent's, not replace it entirely.
class Person {
protected String name;
public void display() {
System.out.println("Name: " + name);
}
}
class Student extends Person {
private int rollNumber;
public void display() {
super.display(); // reuse the parent's version
System.out.println("Roll: " + rollNumber);
}
}final: closing a design on purpose
final on a class means no subclass may ever extend it — Java's own String class is final for exactly this reason, because letting someone override String's methods would break the immutability guarantee the entire language relies on. final on a method means a subclass may inherit it but can never override it, protecting one specific piece of behaviour from being redefined even while the rest of the class stays extensible.
Use final deliberately, as a design statement to future readers: this part of the class is not meant to change, and I am asking the compiler to enforce that rather than relying on a comment. It is the same instinct as CS105ES's const-like discipline, applied to an entire class or method instead of a single variable.
Try it yourself
Extend the Person/Student example: give Person a protected greet() method that prints a generic greeting. Override greet() in Student to print a student-specific greeting after calling the parent's version with super.
Need a hint?
Call super.greet() as the first line of the overridden method, then add the extra print statement after it.
Check the worked solution
Calling super.greet() first, then adding new behaviour, is the extension pattern from this lesson applied directly: Student's greet() is not a replacement, it is the parent's greeting plus something extra, exactly mirroring how the constructor called super(args) to build the Person part first.
class Person {
protected void greet() {
System.out.println("Hello!");
}
}
class Student extends Person {
@Override
protected void greet() {
super.greet();
System.out.println("I am a student.");
}
}Quick check
Why is Java's String class declared final?
Why this lesson exists
Syllabus mapping
Member access rules, super keyword uses, using final keyword with inheritance.
Maps to course outcome CO2.