super Keyword
The super keyword in Java is a special reference used inside a child class to refer to its
immediate parent class. It appears only in inheritance-based code, because its purpose is to connect the
child class with the superclass from which it inherits. When a subclass inherits fields and methods from a
parent class, there are times when the child needs to reach back to the parent version of something. The
child may need to call a parent constructor, access a hidden parent variable, or run a parent method that has
been overridden. The super keyword gives Java a clear way to express that intention.
In simple terms, super means "refer to the immediate parent part of this object." It does not
create a new object and it does not refer to some separate superclass instance floating somewhere in memory.
A child object contains the inherited parent portion and the child-specific portion together. When code uses
super, it is asking Java to look at the parent portion of the current object instead of the
child portion. This idea becomes important when parent and child classes contain members with the same name
or when the child class wants to build on top of parent behavior instead of replacing it completely.
The super keyword is a high-frequency Java interview topic because it sits at the intersection
of inheritance, constructor chaining, method overriding, variable hiding, and object initialization. Many
beginners learn the syntax quickly, but interviews usually test whether the developer understands why
super() must be the first statement in a constructor, why super cannot be used in a
static context, and how super.methodName() behaves when a method is overridden. Understanding
these details makes inheritance much easier to reason about.
What Is super?
super is a keyword that refers to the immediate superclass of the current object. If class
B extends class A, then inside class B, super refers to
the parent class A. It is used only from an instance context because it depends on an actual
object being created. A static method belongs to the class itself, not to a particular object, so Java does
not allow super inside static methods or static blocks.
The most common reason to use super is to remove ambiguity. A child class may define a field
with the same name as a parent field. In that case, writing the field name normally refers to the child
field. Writing super.fieldName tells Java to access the parent field. Similarly, if a child
class overrides a parent method, calling the method normally from inside the child uses the child version.
Calling super.methodName() invokes the parent version directly.
Because super always refers to the immediate parent, it does not skip levels in a multilevel
inheritance hierarchy. If C extends B and B extends A,
then super inside C refers to B, not directly to A. This
keeps inheritance behavior predictable. Each class communicates directly with its immediate parent rather
than reaching through the entire hierarchy.
Why super Is Needed
Inheritance allows a child class to reuse and specialize parent behavior. That reuse creates a practical
question: what should happen when the child class defines a member with the same name as a member in the
parent class? Java needs a precise way to distinguish between the child member and the parent member.
Without super, the child class would have no clean way to refer to a hidden parent field or an
overridden parent method from within the child.
class Parent {
int x = 10;
}
class Child extends Parent {
int x = 20;
void show() {
System.out.println(x); // 20 (child)
System.out.println(super.x); // 10 (parent)
}
}
In this example, both Parent and Child contain a variable named x.
Inside the Child class, writing x refers to the child variable because the child
variable hides the parent variable. Writing super.x explicitly accesses the parent variable.
This is the cleanest way to resolve the naming conflict.
The same idea applies to methods, but the impact is more important. A child class often overrides a parent
method to provide more specific behavior. Sometimes the child wants to run the parent logic first and then
add extra behavior. In that case, super.methodName() avoids duplication. The child does not
rewrite the parent logic; it calls the parent implementation and then extends it.
Uses of super Keyword (Very Important)
1. Access Parent Class Variables
The first use of super is to access a parent class variable when the child class has a variable
with the same name. This situation is called variable hiding. Field access in Java is resolved by reference
type and scope, not by runtime polymorphism. When a child field hides a parent field, the parent field still
exists, but the child field takes priority when accessed directly from the child class.
super.variableName;
Example:
class Parent {
int a = 10;
}
class Child extends Parent {
int a = 20;
void display() {
System.out.println(super.a); // 10
}
}
Although Java allows field hiding, it should be used carefully. In most production code, using the same field name in a parent and child class can make the design harder to read. A developer may not immediately know which value is being used. If the field names represent different concepts, they should usually have different names. If they represent the same concept, the design should usually keep the field in one place and expose it through methods.
2. Call Parent Class Methods
The second use of super is to call a parent class method from a child class. This is most useful
when the child overrides a method but still wants to reuse part of the parent implementation. Without
super, calling the method from inside the overriding method would call the child method again,
which can lead to recursion or incorrect behavior. With super.methodName(), the child class can
explicitly invoke the parent implementation.
class Parent {
void show() {
System.out.println("Parent method");
}
}
class Child extends Parent {
void show() {
super.show();
System.out.println("Child method");
}
}
This approach allows method extension rather than complete replacement. The parent method may contain common setup, validation, logging, or general behavior. The child method can keep that common behavior and add specialized steps. This is a practical pattern when the parent behavior is still correct but not complete enough for the child class.
3. Call Parent Class Constructor (super())
The third and most important use is calling a parent class constructor. Constructors are responsible for
initializing objects. When a child object is created, Java must initialize the parent part before the child
part. This is why every child constructor either explicitly or implicitly calls a parent constructor. The
call is written as super() for a no-argument parent constructor or super(arguments)
for a parameterized parent constructor.
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
super();
System.out.println("Child constructor");
}
}
Output:
Parent constructor
Child constructor
The output shows the constructor order clearly. Even though the program creates a Child object,
the parent constructor runs first. This guarantees that inherited state is initialized before the child class
begins its own initialization. If the parent class has required values, the child constructor must pass those
values using super(arguments).
Important Rules for super()
The rules for super() are strict because constructor execution order must be unambiguous.
First, a call to super() or super(arguments) must be the first statement inside a
constructor. Java does not allow any normal statement before it because the parent part of the object must be
initialized before the child constructor performs its own work. Even a simple print statement before
super() causes a compile-time error.
Second, a constructor can call only one parent constructor. You cannot call super() twice, and
you cannot call both super() and this() in the same constructor. The reason is that
both constructor calls must be the first statement. A constructor can either delegate to another constructor
in the same class using this(), or it can directly call the parent constructor using
super(). It cannot do both directly in the same constructor.
Third, if no constructor call is written explicitly, the compiler automatically inserts
super(). This works only when the parent class has an accessible no-argument constructor. If the
parent class defines only parameterized constructors, the child constructor must explicitly call one of them.
This is one of the most common constructor-related compilation errors in Java inheritance.
super(10);
super() vs this()
super() and this() are both constructor calls, but they serve different purposes.
super() calls a constructor of the immediate parent class. this() calls another
constructor of the same class. Both are used for constructor chaining, but they chain in different
directions. this() chains within the current class, while super() moves from the
current class to the parent class.
| Feature | super() | this() |
|---|---|---|
| Refers to | Parent class | Current class |
| Constructor call | Parent constructor | Current class constructor |
| Position | First statement | First statement |
| Used for | Inheritance | Constructor chaining |
| Combination | Cannot use both together in the same constructor | |
A constructor that uses this() may still eventually cause a parent constructor to run, because
the constructor it calls must either call another constructor or call super(). The important
rule is that each constructor has exactly one first constructor call path. This keeps object initialization
predictable and prevents partially initialized parent or child state.
Where super Cannot Be Used
super cannot be used in a static context. Static methods and static blocks belong to the class,
not to an individual object. Since super refers to the parent portion of the current object,
it requires an object context. There is no current object inside a static method unless one is explicitly
created and referenced through a variable.
static void test() {
// super.x; // Compile-time error
}
This rule is similar to the rule for this. Both this and super depend
on an instance. If a method is static, it can be called without creating an object, so Java cannot allow
direct access to instance-based references there.
super and Method Overriding (Runtime Polymorphism)
Method overriding normally participates in runtime polymorphism. If a parent reference points to a child
object and an overridden method is called, Java executes the child version. The super keyword is
different. When a child class explicitly calls super.methodName(), Java directly invokes the
immediate parent implementation from inside the child. It does not perform the usual runtime dispatch to the
child override.
class Animal {
void sound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
void callParent() {
super.sound();
}
}
This does not mean super breaks polymorphism in the whole program. It simply gives the child
class a way to reuse parent behavior during its own implementation. Code outside the class still experiences
normal polymorphic behavior when it calls overridden methods through parent references.
super Keyword vs this Keyword (Interview Favorite)
The keywords this and super are often compared because both are references used
inside instance code. this refers to the current object from the perspective of the current
class. super refers to the immediate parent part of that same object. They are related, but they
solve different problems. this is commonly used to access current class fields, call current
class constructors, or pass the current object. super is used to access parent class members or
call parent constructors.
| Aspect | this | super |
|---|---|---|
| Refers to | Current object | Parent object |
| Access | Current class members | Parent class members |
| Constructor call | this() | super() |
| Static usage | No | No |
In interviews, a strong answer should explain that this() and super() are
constructor calls, while this and super are object references. The parentheses
matter. super can be used with fields and methods, but super() specifically calls
a parent constructor. Similarly, this refers to the current object, while this()
calls another constructor in the current class.
How super Fits into Object Initialization
Object initialization in Java follows a clear sequence. When a child object is created, memory is allocated for the entire object, including inherited fields. Java then initializes the parent class portion before the child class portion. Parent field initialization and parent constructor execution happen before child field initialization and child constructor execution. This order ensures that inherited behavior has a valid foundation before the child class begins to use or extend it.
The super() call is the visible part of this rule. Even when it is not written, it is still
conceptually present if Java inserts it automatically. This is why a child class cannot avoid parent
construction. A child object is also a parent object from the type system's point of view, so the parent
state must be initialized. If the parent constructor performs validation or requires mandatory data, the
child class must respect that contract.
This behavior is especially important in real codebases where parent classes manage common state. For
example, an Employee superclass may require an employee ID and name. A Manager
subclass should pass those values to the parent constructor using super(id, name), then
initialize manager-specific fields such as department or approval level. This keeps shared employee state in
the parent class and specialized manager state in the child class.
Good Design Practices with super
The super keyword is useful, but heavy use of it can sometimes reveal a design problem. If a
child class constantly accesses parent fields directly, the parent class may be exposing too much internal
detail. Good object-oriented design usually prefers behavior-based access through methods instead of direct
state manipulation. Protected fields may be convenient, but protected methods often provide better control.
Calling parent methods with super is often a clean design when the child extends behavior in a
small and clear way. For example, a parent validate() method may check common rules, and a child
method may call super.validate() before checking child-specific rules. This avoids repeating
common validation logic while still allowing specialization. The important condition is that the parent
behavior must remain meaningful for every child that calls it.
Developers should also avoid creating inheritance hierarchies only to use super. The keyword
exists to support inheritance, but it is not a reason to introduce inheritance by itself. If a class only
needs to use another class's service, composition is usually better. Inheritance should represent a true IS-A
relationship; super should then be used to coordinate parent and child behavior inside that
relationship.
super with Variables, Methods, and Constructors
A helpful way to understand super is to separate its three practical forms. When it is used as
super.variableName, it accesses a field from the immediate parent class. When it is used as
super.methodName(), it calls a method implementation from the immediate parent class. When it is
used as super() or super(arguments), it calls a parent constructor. These uses are
related, but they are not interchangeable.
Accessing parent variables is usually the least common use in well-designed code. It is mainly useful for learning and for rare cases where a child field intentionally hides a parent field. In day-to-day development, direct field hiding is often avoided because it reduces clarity. Calling parent methods is more common because it supports extension of behavior. Calling parent constructors is unavoidable in inheritance because every child object must initialize its parent part.
This difference matters in interviews. If an interviewer asks about super, do not answer only
that it calls a parent constructor. That is just one use. A complete answer says that super can
access parent variables, call parent methods, and invoke parent constructors. Then it should explain that
super() specifically refers to constructor invocation and must be the first statement in a
constructor.
Common Traps Around super
One common trap is assuming super can access members from any ancestor class. In a multilevel
hierarchy, super refers only to the immediate parent. If class C extends
B and class B extends A, then super inside
C points to B. Class C cannot directly write a special keyword to
skip B and access A. If behavior from A is needed, class
B must expose it or call it as part of its own method.
Another trap is confusing overridden methods with hidden fields. Instance methods are polymorphic. If a child
overrides a parent method, Java chooses the method implementation based on the runtime object type. Fields do
not behave that way. If a child field has the same name as a parent field, field access is resolved using
the reference type and scope. This is why super.x is useful for fields, while
super.show() is useful for bypassing an overridden method inside the child.
A third trap is believing that super() is optional in every situation. It is optional only when
the compiler can safely insert a no-argument parent constructor call. If the parent has no accessible
no-argument constructor, the child must explicitly call an available parent constructor with matching
arguments. The compile-time error is not about inheritance being broken; it is about incomplete object
initialization.
Another frequent mistake is trying to use super from a static method. Static methods do not run
against a current object, so there is no current parent portion to refer to. If a static method needs to use
behavior from another class, it should call static members through the class name or create an object and
use instance methods through that object. It should not try to use super.
Real-World Example of super Usage
Imagine an application that manages different types of employees. A base Employee class stores
common details such as employee ID, name, and base salary. A Manager class extends
Employee and adds a department and bonus calculation. The Manager constructor can
call super(id, name, salary) to initialize the common employee details, then initialize the
department field in the manager class. This keeps shared employee initialization in one place.
The same child class may override a method such as calculatePay(). The parent method may
calculate normal salary, while the child method may call super.calculatePay() and then add a
manager bonus. This is a clean use of inheritance because the child is still an employee, and the parent
calculation remains part of the child calculation. The child does not duplicate the base salary logic; it
extends it.
In testing or debugging such code, super also makes intention visible. When a developer reads
super.calculatePay(), it is clear that the child method intentionally includes parent behavior.
This is better than copying the parent code into the child method, because copying creates duplicate logic
and makes future corrections harder.
super and Access Modifiers
The ability to use super does not ignore Java access rules. A child class can use
super only to access parent members that are visible from the child class. Public members are
accessible. Protected members are accessible from subclasses, including subclasses in different packages.
Package-private members are accessible only if the child class is in the same package. Private members are
not directly accessible through super.
This point is important because some beginners think super is a special bypass for
encapsulation. It is not. If a parent field is private, writing super.fieldName from the child
class causes a compile-time error. The child must use a visible method provided by the parent class. This
preserves the parent class's control over its internal state.
In well-designed inheritance, parent classes usually expose protected or public methods for behavior that subclasses are expected to reuse. They keep implementation details private. This allows subclasses to extend the parent safely without depending on every internal field.
Best Practices for Interview and Project Use
In interviews, explain super in a structured way. Start by saying that it refers to the
immediate parent class object in an instance context. Then describe the three uses: accessing parent
variables, calling parent methods, and invoking parent constructors. After that, mention the rules:
super() must be the first statement in a constructor, super cannot be used in a
static context, and it cannot access private parent members directly.
In project code, use super when it makes the parent-child relationship clearer. Use
super() to pass required initialization data to the parent. Use super.methodName()
when the child behavior is truly an extension of parent behavior. Avoid using super to patch a
poor inheritance hierarchy. If the child class depends too heavily on parent internals, revisit the design.
A concise mental model is this: this looks at the current class view of the object, while
super looks at the immediate parent class view of the same object. Once this model is clear,
most examples involving variable hiding, method overriding, constructor chaining, and static restrictions
become much easier to understand.
super Keyword Examples (With Output)
1. Using super to Access Parent Variable
class A {
int x = 10;
}
class B extends A {
int x = 20;
void show() {
System.out.println(super.x);
}
public static void main(String[] args) {
new B().show();
}
}
Explanation: super.x accesses parent variable.
Output: 10
2. Variable Hiding Without super
class A {
int x = 10;
}
class B extends A {
int x = 20;
void show() {
System.out.println(x);
}
public static void main(String[] args) {
new B().show();
}
}
Explanation: Child variable hides parent variable.
Output: 20
3. Using super to Call Parent Method
class A {
void show() {
System.out.println("Parent");
}
}
class B extends A {
void show() {
super.show();
System.out.println("Child");
}
public static void main(String[] args) {
new B().show();
}
}
Explanation: super.show() calls parent version.
Output:
Parent
Child
4. Overriding Without super
class A {
void show() {
System.out.println("A");
}
}
class B extends A {
void show() {
System.out.println("B");
}
public static void main(String[] args) {
new B().show();
}
}
Explanation: Parent method completely overridden.
Output: B
5. super() Calling Parent Constructor
class A {
A() {
System.out.println("Parent Constructor");
}
}
class B extends A {
B() {
super();
System.out.println("Child Constructor");
}
public static void main(String[] args) {
new B();
}
}
Explanation: super() calls parent constructor.
Output:
Parent Constructor
Child Constructor
6. Implicit super() Call
class A {
A() {
System.out.println("Parent");
}
}
class B extends A {
B() {
System.out.println("Child");
}
public static void main(String[] args) {
new B();
}
}
Explanation: Compiler inserts super() automatically.
Output:
Parent
Child
7. Calling Parameterized Parent Constructor
class A {
A(int x) {
System.out.println(x);
}
}
class B extends A {
B() {
super(10);
}
public static void main(String[] args) {
new B();
}
}
Explanation: Required when parent has no default constructor.
Output: 10
8. Compile Error Without super() (Parameterized Parent)
class A {
A(int x) {}
}
class B extends A {
// B() {} // Compile-time error
}
Explanation: Parent has no no-arg constructor, so super(x) is mandatory.
9. super() Must Be First Statement
class A {
A() {}
}
class B extends A {
B() {
// System.out.println("Hi");
// super(); // Compile-time error
}
}
Explanation: super() must be the first line in constructor.
10. Using super in Multilevel Inheritance
class A {
void show() {
System.out.println("A");
}
}
class B extends A {
void show() {
super.show();
System.out.println("B");
}
}
class C extends B {
void show() {
super.show();
System.out.println("C");
}
public static void main(String[] args) {
new C().show();
}
}
Explanation: Calls flow upward through hierarchy.
Output:
A
B
C
11. super Cannot Access Child Members
class A {}
class B extends A {
int x = 10;
void test() {
// super.x; // Compile-time error
}
}
Explanation: super refers only to parent members.
12. super with Method Overriding + Variables
class A {
int x = 10;
void show() {
System.out.println("A");
}
}
class B extends A {
int x = 20;
void show() {
System.out.println(super.x);
super.show();
System.out.println(x);
}
public static void main(String[] args) {
new B().show();
}
}
Explanation: Demonstrates full usage.
Output:
10
A
20
13. super with final Method
class A {
final void show() {
System.out.println("Final");
}
}
class B extends A {
void test() {
super.show();
}
public static void main(String[] args) {
new B().test();
}
}
Explanation: final methods can be called but not overridden.
Output: Final
14. super with Static Methods (Not Polymorphic)
class A {
static void show() {
System.out.println("A");
}
}
class B extends A {
static void show() {
System.out.println("B");
}
void test() {
super.show();
}
public static void main(String[] args) {
new B().test();
}
}
Explanation: Static methods are hidden.
Output: A
15. Constructor Execution Order (Real Interview Favorite)
class A {
A() {
System.out.println("A");
}
}
class B extends A {
B() {
System.out.println("B");
}
}
class C extends B {
C() {
System.out.println("C");
}
public static void main(String[] args) {
new C();
}
}
Explanation: Constructors execute from top to bottom through the inheritance chain.
Output:
A
B
C
16. super vs this (Side by Side)
class A {
int x = 10;
}
class B extends A {
int x = 20;
void show() {
System.out.println(this.x);
System.out.println(super.x);
}
public static void main(String[] args) {
new B().show();
}
}
Explanation: this refers to the current object, while super refers to the parent object.
Output:
20
10
17. super in Copy-Style Constructor
class A {
int x;
A(int x) {
this.x = x;
}
}
class B extends A {
B(int x) {
super(x);
}
public static void main(String[] args) {
B b = new B(15);
System.out.println(b.x);
}
}
Explanation: Parent initialization reused.
Output: 15
18. super Cannot Be Used in Static Context
class A {
int x = 10;
}
class B extends A {
static void test() {
// super.x; // Compile-time error
}
}
Explanation: super needs object context.
19. Common Interview Trap
class A {
void show() {
System.out.println("A");
}
}
class B extends A {
static void show() {
System.out.println("B");
}
}
Explanation: This is not overriding. Static methods cannot override instance methods.
20. Interview Summary – super Keyword
class A {
int x = 10;
void show() {
System.out.println("A");
}
}
class B extends A {
void display() {
System.out.println(super.x);
super.show();
}
public static void main(String[] args) {
new B().display();
}
}
Explanation:
- Access parent variables
- Call parent methods
- Invoke parent constructors
Output:
10
A
Common Beginner Mistakes
- Using super in static methods
- Forgetting super() when parent has no default constructor
- Calling super() not as first statement
- Confusing super with this
- Expecting super to access grandparent directly
Interview-Ready Answers
Short Answer
The super keyword refers to the immediate parent class object and is used to access parent class members.
Detailed Answer
In Java, the super keyword is used in inheritance to access parent class variables, methods, and constructors. It helps resolve naming conflicts, supports constructor chaining, and allows invoking overridden parent methods. super() must be the first statement in a constructor.
Key Takeaway
The super keyword enables controlled access to parent class behavior. Proper use of super ensures correct initialization, clean overriding, and predictable inheritance behavior.