Advanced Concepts in Java Inheritance
1. Access Control and Inheritance
Access control in Java determines how class members (fields, methods, constructors) are inherited and visible across packages and subclasses.
Notes:
- private: Not inherited directly. Accessible only within the same class. Use getters/setters to make it visible.
- default (package-private): Accessible only within the same package. Not visible to subclasses in other packages.
- protected: Accessible in the same package and by subclasses even in other packages.
- public: Accessible everywhere and fully inherited.
class Vehicle {
private int chassisNumber = 101;
protected String brand = "NBKRIST Motors";
public void show() {
System.out.println("Brand: " + brand);
}
}
class Car extends Vehicle {
void display() {
System.out.println("Manufactured by: " + brand);
}
}
public class AccessDemo {
public static void main(String[] args) {
Car c = new Car();
c.show();
c.display();
}
}
🔐 Pro Tip: Combine protected and encapsulation (getters/setters) to design safe and flexible inheritance structures.
2. Application of Keyword super
The super keyword bridges subclass and superclass, enabling constructor chaining and parent method access.
💡 Focus:
Using super we can access hidden members, invoke parent constructors, or call overridden methods.
Although private members are not directly accessible, we can initialize or read them using super-invoked public or protected methods of the superclass.
class Vehicle {
private int chassisNumber;
Vehicle(int num){ this.chassisNumber = num; }
protected void showInfo() {
System.out.println("Chassis Number: " + chassisNumber);
}
}
class Bus extends Vehicle {
Bus(int n){
super(n); // initializes private member through superclass constructor
}
void display(){ super.showInfo(); }
}
public class SuperKeywordDemo {
public static void main(String[] args){
Bus b = new Bus(501);
b.display();
}
}
⚙️ Pro Tip: Always use super() as the first statement in subclass constructors — it ensures parent class initialization first.
3. Method Overriding and Dynamic Dispatch
Overriding redefines a superclass method in the subclass. When called via a superclass reference pointing to a subclass object, Java dynamically binds the appropriate method at runtime — this is known as Dynamic Method Dispatch.
class Vehicle {
void run(){ System.out.println("NBKRIST Vehicle running..."); }
}
class Car extends Vehicle {
void run(){ System.out.println("Car cruising..."); }
}
class Bus extends Vehicle {
void run(){ System.out.println("Bus moving..."); }
}
public class DispatchDemo {
public static void main(String[] args){
Vehicle v;
v = new Car(); v.run();
v = new Bus(); v.run();
}
}
🚀 Pro Tip: Dynamic method dispatch enables scalable and extensible design — ideal for plug-in architectures.
📝 Practice Questions
Q1. What is the difference between private and protected access in inheritance?
Answer: Private is not accessible outside the class. Protected allows access within subclasses (even in other packages).
Q2. How can you access a private member of the superclass?
Answer: Indirectly via public/protected getter or through super() constructor initialization.
Q3. What is the purpose of using
super in constructors?
Answer: To call the parent constructor and initialize inherited properties before executing subclass initialization.
Q4. Define Dynamic Method Dispatch.
Answer: It is Java’s mechanism to decide which overridden method to execute at runtime based on the actual object type.
🔑 Key Takeaways
- Access modifiers define visibility and inheritance scope.
super ensures proper superclass initialization and controlled access.
- Dynamic method dispatch brings runtime flexibility and polymorphism.
- Encapsulation + inheritance = strong OOP design.