Introduction
Inheritance in Java is a core object-oriented feature allowing one class to acquire the properties and behaviors of another using the extends keyword. It promotes reusability, hierarchical relationships, and structured code organization. Interviewers evaluate understanding of inheritance rules, constructor execution order, method dispatching, access control impacts, memory behavior, and limitations such as single inheritance. Mastery of inheritance is essential for designing maintainable class hierarchies, applying polymorphism effectively, and avoiding common pitfalls like misuse of tight coupling or exposing internal state unnecessarily.
What Interviewers Expect
- Clear explanation of how inheritance works and its rules.
- Knowledge of constructor execution order in inheritance hierarchy.
- Understanding of method resolution, overriding, and dynamic dispatch.
- Ability to differentiate between inheritance, composition, and interfaces.
- Awareness of memory layout, parent-child relationships, and JVM behavior.
Table of Contents
- Interview Questions
- Scenario-Based Interview Questions
- Common Mistakes
- FAQs
Interview Questions
Q1. What is inheritance in Java?
- Inheritance allows a class (child) to acquire fields and methods from another class (parent) using the extends keyword.
- It enables reusability by sharing common attributes across related classes.
- JVM treats inherited members as part of the subclass during runtime method resolution.
- Parent constructor executes first, establishing base initialization before child-specific logic.
- Inheritance creates an IS-A relationship which should be meaningful and logical.
- Improper inheritance can lead to tight coupling and complex hierarchies.
Follow-up Questions:
- What is the difference between IS-A and HAS-A?
- When should inheritance be avoided?
Q2. What are the different types of inheritance supported in Java?
- Single Inheritance (one parent, one child) is directly supported in Java.
- Multilevel Inheritance (class inherits from a child of another class) is allowed.
- Hierarchical Inheritance (multiple classes inherit from one parent) is allowed.
- Java does not support Multiple Inheritance with classes to avoid ambiguity issues.
- Interfaces allow a form of multiple inheritance since a class can implement multiple interfaces.
- JVM handles inheritance trees during class loading and method resolution.
Follow-up Questions:
- Why is multiple inheritance not allowed?
- How do interfaces solve diamond problems?
Q3. How does constructor execution occur in inheritance?
- Parent constructor always executes before the child constructor.
- JVM enforces this by placing an implicit super() call if not written explicitly.
- If parent has no default constructor, child must explicitly call a matching super() constructor.
- Constructor chaining proceeds top-down through the hierarchy.
- Final fields in parent must be initialized before child accesses them.
- This ensures consistent and predictable initialization order.
Follow-up Questions:
- What if parent constructor throws an exception?
- Can constructor execution order be altered?
Q4. How does method overriding relate to inheritance?
- Method overriding allows a subclass to provide a new implementation of a method inherited from the parent.
- Only inherited non-final, non-static, non-private methods can be overridden.
- JVM uses dynamic method dispatch to select the overridden method at runtime.
- Overriding enables polymorphic behavior where parent references point to child objects.
- Method signature must match exactly for overriding to occur.
- Overriding facilitates extensibility without modifying parent code.
Follow-up Questions:
- Why are static methods not overridden?
- How does JVM select overridden methods at runtime?
Q5. What cannot be inherited in Java?
- Constructors are not inherited because each class must define its own initialization logic.
- Private members are not accessible directly but can be used via getters/setters.
- Static methods are inherited but cannot be overridden, only hidden.
- Final methods cannot be overridden in child classes.
- Final classes cannot be extended at all.
- JVM enforces these restrictions for class safety and consistency.
Follow-up Questions:
- Why are constructors not inheritable?
- How does method hiding differ from overriding?
Q6. What is the difference between inheritance and composition?
- Inheritance creates an IS-A relationship, while composition forms a HAS-A relationship.
- Composition is more flexible because contained objects can be replaced at runtime.
- Inheritance tightly couples parent and child classes, affecting maintainability.
- Composition enables code reuse without exposing parent internals.
- Inheritance is resolved at compile time; composition is resolved via object references at runtime.
- Many design patterns favor composition over inheritance.
Follow-up Questions:
- Why is composition preferred in modern design?
- When should inheritance be used instead?
Q7. How does Java handle multiple inheritance?
- Java does not allow multiple inheritance with classes to avoid ambiguity known as the diamond problem.
- Diamond problem occurs when two parent classes provide different implementations of a method inherited by the child.
- Java solves this by allowing multiple inheritance through interfaces instead of classes.
- Interfaces can have default methods, but conflicts must be resolved explicitly by overriding in the child class.
- JVM ensures clear method resolution order when interfaces are involved.
- This design maintains simplicity and avoids unpredictable method resolution paths.
Follow-up Questions:
- How does C++ handle multiple inheritance?
- How do interfaces resolve diamond conflicts?
Q8. What is method hiding in inheritance?
- Method hiding occurs when a subclass defines a static method with the same signature as a static parent method.
- Hidden static methods do not participate in overriding because overriding applies only to instance methods.
- Method selection is based on reference type, not object type, for static methods.
- JVM binds static methods at compile time using static binding.
- Hiding does not achieve polymorphism; it only shadows the parent implementation.
- Developers must avoid method hiding as it causes confusion and ambiguity.
Follow-up Questions:
- How does static binding differ from dynamic binding?
- Can static methods use @Override annotation?
Q9. How does inheritance affect memory allocation in Java?
- When a subclass object is created, memory for both parent and child fields is allocated in a single heap block.
- Parent fields exist as part of the child object even though they are defined separately in the class hierarchy.
- JVM initializes parent fields first, then child fields during object creation.
- Method tables (vtable) store overridden method references for dynamic dispatch.
- Inherited methods do not duplicate memory; they are referenced through method tables.
- This memory model supports efficient polymorphism and inheritance behavior.
Follow-up Questions:
- How does vtable change when methods are overridden?
- Does inheritance increase object size?
Q10. What is multilevel inheritance?
- Multilevel inheritance occurs when a class inherits from a class which itself inherits from another class.
- Example: Class C extends B, and B extends A.
- Constructors execute in A → B → C order, ensuring top-down initialization.
- Method overriding may occur at multiple levels, and JVM resolves the most specific overridden version.
- Multilevel inheritance supports hierarchical modeling of real-world entities.
- Deep hierarchies can become complex and reduce maintainability.
Follow-up Questions:
- How does dynamic method dispatch work in deep hierarchies?
- What are drawbacks of deep inheritance chains?
Q11. How does access modifier affect inheritance?
- public members are accessible everywhere, including child classes across packages.
- protected members are accessible in child classes even if in different packages.
- default (package-private) members are accessible only within the same package, not in subclasses outside it.
- private members are not directly inherited but can be accessed via public or protected methods.
- Access modifiers determine visibility of fields and methods across inheritance boundaries.
- Improper visibility decisions can break encapsulation or limit reuse.
Follow-up Questions:
- Why is private not inheritable?
- How does protected differ from default?
Q12. What is hierarchical inheritance?
- Hierarchical inheritance occurs when multiple child classes inherit from the same parent class.
- All child classes share the common behavior defined in the parent class.
- Each child can override or extend parent behavior as needed.
- Parent code benefits from reuse and reduces duplication across siblings.
- JVM resolves overridden methods in each child independently.
- This structure is common in framework designs and domain models.
Follow-up Questions:
- How does hierarchical inheritance differ from multilevel inheritance?
- Can hierarchical inheritance cause method conflicts?
Q13. Can a subclass override static, private, or final methods?
- Static methods cannot be overridden; they can only be hidden.
- Private methods cannot be accessed or overridden because they are not inherited.
- Final methods cannot be overridden to preserve intended behavior.
- Overriding applies only to inherited, non-final, instance-level methods.
- JVM enforces these rules at compile time for safety and consistency.
- Attempting to override invalid methods results in compilation errors.
Follow-up Questions:
- Why is overriding private methods impossible?
- Why are final methods important in class design?
Q14. What is dynamic method dispatch?
- Dynamic method dispatch is the mechanism by which JVM selects the overridden method at runtime.
- Selection is based on the actual object type, not the reference type.
- Supports runtime polymorphism where the most specific overridden method executes.
- JVM uses vtable or virtual method tables to resolve method calls dynamically.
- Dynamic dispatch enables extensibility without modifying existing code.
- It is central to inheritance-based polymorphism.
Follow-up Questions:
- How does dynamic dispatch differ from static binding?
- What role does vtable play in dispatch?
Q15. What is object slicing in inheritance?
- Object slicing occurs in languages like C++ when a derived object is assigned to a base object, slicing off derived fields.
- Java does not support object slicing because objects are referenced, not copied by value.
- Parent references can refer to child objects, but actual object remains intact in heap.
- JVM uses reference semantics to avoid slicing and preserve object integrity.
- Method access is limited by reference type but object state remains complete.
- This design avoids common pitfalls of value slicing in inheritance.
Follow-up Questions:
- Why does Java avoid object slicing?
- How do reference semantics help polymorphism?
Q16. Why is inheritance not always recommended?
- Improper inheritance leads to tight coupling between child and parent classes.
- Changes in parent may unknowingly break child behavior.
- Deep inheritance trees are hard to understand and maintain.
- Inheritance exposes internal details that should remain hidden.
- Composition is often preferred because it allows dynamic behavior changes.
- Inheritance is best used only when IS-A relationship is logical and stable.
Follow-up Questions:
- How does composition reduce coupling?
- When is inheritance unavoidable?
Q17. How does overriding affect performance?
- Overriding uses dynamic method dispatch, which introduces a small lookup overhead at runtime.
- Performance impact is minimal due to JVM optimizations like inlining and hotspot compilation.
- JVM may inline frequently invoked overridden methods for better performance.
- Method tables ensure fast resolution despite runtime dispatch.
- Performance issues arise only if inheritance chains are excessively deep.
- Correct use of overriding enhances flexibility without major performance cost.
Follow-up Questions:
- What is method inlining?
- How does JIT optimize overridden methods?
Q18. Can a subclass reduce the visibility of an inherited method?
- No, a subclass cannot reduce the access level of an overridden method.
- Doing so would break the Liskov Substitution Principle (LSP) and violate inheritance integrity.
- Overriding method must have same or broader visibility than parent’s method.
- JVM enforces this rule at compile time to preserve substitutability.
- Increasing visibility (e.g., protected → public) is allowed.
- Reducing visibility causes compilation error.
Follow-up Questions:
- Why is reducing visibility prohibited?
- How does LSP relate to inheritance?
Q19. What is the role of super keyword in inheritance?
- super is used to access parent class methods and variables.
- super() calls the parent constructor and must be the first statement.
- super can differentiate parent methods when overridden in child.
- super helps reuse parent code without duplication.
- JVM resolves super calls based on parent’s implementation, not child.
- super cannot be used to access private members directly.
Follow-up Questions:
- Can super and this be used together?
- How does super help avoid shadowing?
Q20. What is shadowing in inheritance?
- Shadowing occurs when a subclass declares a variable with the same name as a variable in the parent class.
- Access to the parent variable is hidden unless explicitly referenced using super.variableName.
- Shadowing affects only fields, not methods (methods use overriding).
- JVM resolves field access based on reference type, not object type.
- Shadowing leads to confusion and reduces code clarity.
- Shadowing should be avoided unless necessary for backward compatibility.
Follow-up Questions:
- How does shadowing differ from method hiding?
- Why is shadowing discouraged?
Q21. Can a subclass access private members of the parent class?
- No, private members are not accessible directly by subclasses.
- Private members are inherited logically but not accessible due to encapsulation rules.
- Subclasses can interact with private fields only through protected/public getter–setter methods.
- JVM enforces access restrictions at compile time and runtime.
- Accessing private members using reflection is possible but discouraged.
- Encapsulation ensures parent internal state remains protected from unintended modification.
Follow-up Questions:
- Why are private members not visible to subclasses?
- How do getter methods support inheritance?
Q22. Can a class extend multiple classes indirectly?
- Yes, Java supports multilevel inheritance which means ClassC can extend ClassB which extends ClassA.
- This forms an indirect inheritance chain covering multiple levels.
- Indirect inheritance does not violate Java’s single inheritance rule since each class has only one direct parent.
- Method resolution is still predictable due to structured inheritance hierarchy.
- JVM resolves overridden methods by traversing the chain from bottom to top.
- Indirect inheritance helps in layered class designs and code organization.
Follow-up Questions:
- How deep should inheritance hierarchies be?
- When should inheritance be replaced with composition?
Q23. How does inheritance affect method resolution during runtime?
- Method resolution uses dynamic dispatch to select the most overridden version of a method.
- JVM determines the actual object type at runtime to pick the method implementation.
- If no overriding exists, parent method executes.
- Method tables (vtable) store references to resolved method implementations.
- This approach supports polymorphism and extensibility in Java.
- Resolution happens at runtime even if reference is of parent type.
Follow-up Questions:
- What happens if method is final?
- How does Java handle overridden methods internally?
Q24. What happens if parent and child classes have constructors with same parameters?
- Constructors are not inherited, so having same parameter signature in both classes is allowed.
- Each class defines its own constructor independently.
- Child constructor cannot override parent constructor because constructors are not part of method dispatch.
- JVM differentiates constructors based on class identity, not signature alone.
- Child must call parent constructor explicitly using super(parameters).
- Duplicate constructor signatures do not create conflicts across inheritance levels.
Follow-up Questions:
- Why can constructors not be overridden?
- How does Java enforce constructor call order?
Q25. How does inheritance impact garbage collection?
- Garbage collection works the same regardless of inheritance hierarchy.
- Parent and child objects form a single memory block in heap and are freed together.
- If references to the object are lost, GC marks the entire object for cleanup.
- Inheritance does not create multiple separate GC units; the object is treated as one.
- Finalizers (deprecated) follow hierarchy but are discouraged.
- GC handles inherited objects using standard mark-and-sweep or G1 algorithms.
Follow-up Questions:
- How do strong, weak, and soft references affect GC?
- Does inheritance increase GC pressure?
Q26. What is hybrid inheritance and does Java support it?
- Hybrid inheritance is a combination of more than one type of inheritance model.
- Java partially supports hybrid inheritance through interfaces.
- Hybrid structures using classes alone are not supported due to multiple inheritance restrictions.
- Using multiple interfaces + class inheritance creates hybrid behavior.
- Default methods in interfaces must be handled carefully to avoid conflict.
- JVM resolves conflicts using explicit overriding rules.
Follow-up Questions:
- How do interfaces solve hybrid inheritance issues?
- What is the diamond problem?
Q27. Can you prevent inheritance in Java?
- Yes, by marking a class as final inheritance is prevented.
- Final class cannot be extended and ensures immutability or security.
- Constructors of final classes still execute normally but subclassing is blocked.
- Methods can also be marked final to prevent overriding.
- JVM checks final restrictions at both compile and runtime.
- This is useful when class behavior must remain consistent.
Follow-up Questions:
- Why are wrapper classes final?
- How do you restrict inheritance selectively?
Q28. What is the difference between overriding and overloading in inheritance?
- Overriding modifies parent class method behavior in child class; overloading provides multiple versions of a method within same class.
- Overriding requires inheritance; overloading does not.
- Overriding supports runtime polymorphism; overloading supports compile-time polymorphism.
- Signatures must match exactly for overriding; must differ for overloading.
- JVM uses dynamic dispatch for overriding and static binding for overloading.
- Return types can differ covariantly in overriding but not in overloading.
Follow-up Questions:
- What is covariant return type?
- Which performs better: overriding or overloading?
Q29. Can a subclass access protected members of parent class in another package?
- Yes, protected members are accessible in subclasses even if they are in different packages.
- Access must be through subclass reference and not via parent instance.
- Protected access requires inheritance relationship for cross-package visibility.
- JVM enforces these rules strictly during compilation.
- Protected strikes balance between encapsulation and inheritance flexibility.
- Incorrect usage can expose internal details unintentionally.
Follow-up Questions:
- How does protected differ from default access?
- Can protected create security issues?
Q30. How does inheritance help polymorphism?
- Inheritance allows child classes to override parent methods.
- Parent references can refer to child objects enabling polymorphic behavior.
- JVM resolves methods based on object type during runtime (dynamic dispatch).
- Polymorphism enhances flexibility and extensibility of code.
- Design patterns rely heavily on polymorphism (Factory, Strategy, Template Method).
- Inheritance is a prerequisite for runtime polymorphism in Java.
Follow-up Questions:
- How does polymorphism improve maintainability?
- Can polymorphism exist without inheritance?
Q31. What is a subclass constructor expected to do first?
- Subclass constructor must call super() implicitly or explicitly as its first statement.
- This ensures parent initialization occurs before child initialization.
- If parent has no default constructor, child must specify super(parameters).
- Failure to call an appropriate constructor leads to compile-time error.
- JVM enforces constructor chaining rules strictly.
- This maintains consistency of the object lifecycle across inheritance layers.
Follow-up Questions:
- Can constructor chaining be circular?
- What happens if super() throws an exception?
Q32. What is upcasting and how is it used in inheritance?
- Upcasting refers to assigning a child object to a parent reference.
- It allows using parent type to represent multiple child types uniformly.
- Upcasting enables polymorphism and generic APIs.
- JVM resolves overridden methods dynamically based on actual object type.
- Upcasting is implicit and safe because child is always a parent.
- Upcasting hides child-specific methods unless downcasted.
Follow-up Questions:
- What is the risk of downcasting?
- Can upcasting cause data loss?
Q33. What is downcasting and when is it needed?
- Downcasting assigns a parent reference back to a child reference.
- It is required when child-specific methods need to be accessed.
- Downcasting must be done carefully because invalid casts cause ClassCastException.
- instanceof should be used before downcasting to ensure type safety.
- JVM performs runtime checks to validate cast correctness.
- Downcasting is useful in polymorphic collections containing parent references.
Follow-up Questions:
- When is ClassCastException thrown?
- Why must instanceof be used before downcasting?
Q34. What is the difference between inheritance and interface implementation?
- Inheritance extends class behavior while interface implementation provides a contract for behavior.
- A class can extend only one parent but can implement multiple interfaces.
- Interfaces do not carry state, while parent classes do.
- Interfaces support multiple inheritance traits; classes do not.
- Method resolution for interfaces requires conflict resolution when default methods collide.
- Classes provide reusable implementation, whereas interfaces define required behavior.
Follow-up Questions:
- Can interface methods conflict?
- How are conflicts resolved?
Q35. Can a subclass override a method and throw more exceptions?
- No, a subclass cannot throw broader checked exceptions than the parent method.
- It may throw fewer or narrower (subclass) checked exceptions.
- Unchecked exceptions can be added freely.
- JVM enforces checked exception compatibility for overriding.
- This ensures backward compatibility and prevents unexpected failures.
- Throwing wider exceptions breaks Liskov Substitution Principle.
Follow-up Questions:
- What is exception narrowing?
- Can overridden methods remove exceptions completely?
Q36. What is the effect of final class on inheritance?
- A final class cannot be extended, ensuring behavior remains unchanged.
- JVM prevents inheritance attempts at compile time.
- Many core Java classes like String and wrapper classes are final for security and immutability.
- Final class may still implement interfaces.
- Final methods within a class cannot be overridden.
- Final classes improve reliability and prevent accidental extension.
Follow-up Questions:
- Why are Strings immutable?
- Why does final improve security?
Q37. What is covariant return type in inheritance?
- Covariant return type allows overridden methods to return a subtype of the return type declared in the parent method.
- Ensures better type compatibility and reduces need for casting.
- JVM allows covariant returns only for reference types.
- Covariant returns do not affect method signature — only return type.
- Supports more flexible and overridable method designs.
- Common in factory-like overridden methods.
Follow-up Questions:
- Why is covariant return type not supported for primitives?
- How do covariant returns help API design?
Q38. How does inheritance affect equals() and hashCode() implementation?
- Subclasses overriding equals() must ensure consistency with the parent class’s equality rules.
- hashCode() must be overridden whenever equals() is overridden.
- Mismatched implementations lead to broken behavior in HashMap and HashSet.
- Using instanceof in equals() can break symmetry in inheritance.
- JVM relies on consistent equality rules for hashing-based collections.
- Best practice: make classes final or use composition to avoid equality conflicts.
Follow-up Questions:
- Why does equals() symmetry break with inheritance?
- When is composition preferred for equals() consistency?
Q39. Can inheritance cause memory leaks?
- Improper inheritance can lead to memory leaks if child objects unintentionally retain references to parent resources.
- Leaking this reference inside constructors exposes incomplete objects to external use.
- Parent classes holding static references to children can also cause leaks.
- Circular dependencies between parent and child hinder garbage collection.
- Memory leaks occur due to misuse, not inheritance itself.
- Proper encapsulation and design patterns help avoid leaks.
Follow-up Questions:
- How to detect memory leaks?
- What is object escape?
Q40. What are best practices for using inheritance in Java?
- Use inheritance only when IS-A relationship is clear and stable.
- Prefer composition for flexible and maintainable designs.
- Avoid deep inheritance hierarchies.
- Override methods carefully and consistently.
- Use final to prevent unwanted extension.
- Document parent-child relationships clearly.
Follow-up Questions:
- When is inheritance the only choice?
- How does composition improve testability?
Scenario-Based Interview Questions
Scenario 1: A subclass method is not being executed even though it overrides the parent method. Why?
- The reference type might be of parent class, and method might be static (static methods use hiding, not overriding).
- The method signature may not match exactly; even slight differences prevent overriding.
- The child method may have reduced visibility causing compilation issues.
- Incorrect annotations or accidental overloading may be occurring instead of overriding.
- JVM chooses overridden method based on actual object type, not reference type.
- Debugging must verify method signatures and access levels.
Scenario 2: Parent class does not have a default constructor but subclass is failing compilation. Why?
- If parent lacks a no-argument constructor, subclass must explicitly call super(parameters).
- Compiler adds implicit super() only when parent has a default constructor.
- Failure to call matching parent constructor leads to compile-time error.
- JVM requires strict constructor chaining to preserve initialization order.
- This scenario is common when adding custom constructors to parent class.
- Fix is to call the correct parent constructor explicitly.
Scenario 3: Two interfaces contain same default method. How does Java resolve it?
- Java forces the implementing class to override the conflicting default method.
- The implementing class must specify which interface’s version to call using InterfaceName.super.method().
- JVM rejects ambiguous default method inheritance.
- This prevents accidental multiple inheritance behavior.
- Conflict resolution ensures deterministic method selection.
- This rule preserves clarity and avoids diamond problem.
Scenario 4: How would you replace inheritance with composition?
- Identify behaviors inherited from parent and extract them into separate helper classes.
- Use HAS-A relationship by holding references to helper objects.
- Delegate tasks to helper objects instead of overriding methods.
- Allows replacing helper classes at runtime for flexible behavior.
- Improves testability by mocking dependencies.
- Reduces tight coupling caused by inheritance.
Scenario 5: A subclass overrides equals() but not hashCode(). What goes wrong?
- Objects that are equal according to equals() will produce different hash codes.
- Inconsistent behavior breaks HashSet, HashMap, and other hashing collections.
- JVM may place object in incorrect buckets resulting in lookup failures.
- Contracts between equals() and hashCode() are violated.
- Avoid overriding equals() without also overriding hashCode().
- Best practice is to keep immutable classes or use composition.
Common Mistakes
- Using inheritance when composition is more appropriate.
- Creating deep and fragile inheritance chains.
- Failing to override methods correctly due to mismatched signatures.
- Misusing protected access and exposing internal state.
- Overusing inheritance for code reuse instead of design clarity.
Quick Revision Snapshot
- Inheritance enables IS-A relationships.
- Constructors are not inherited; super() required.
- Method overriding enables runtime polymorphism.
- Protected allows cross-package inheritance.
- Interfaces allow multiple inheritance.
- Prefer composition over inheritance.
FAQs
Can inheritance be disabled?
Yes, by marking a class as final.
Can we inherit private members?
They are inherited logically but not accessible directly.
Does inheritance improve performance?
No, but it improves code reuse and maintainability.
Conclusion
Inheritance in Java enables structured code reuse, supports polymorphism, and allows hierarchical class design. Understanding constructor chaining, method overriding, and JVM behavior ensures safe and maintainable use of inheritance in real-world systems.
The next recommended topic is: Polymorphism in Java.