Java 'this' and 'super' Keywords

Understand how to reference the current object and parent class using 'this' and 'super' keywords in Java

What is the 'this' Keyword?

The 'this' keyword is a reference variable that refers to the current object. It's like saying "this object right here" when you're inside a class.

Think of 'this' as a mirror that points back to the object itself. When you're inside a method or constructor, 'this' helps you talk about the object you're currently working with.

  • this refers to the current class object
  • Used to differentiate between instance variables and parameters with the same name
  • Can be used to call current class methods and constructors
  • Helps avoid naming conflicts and makes code clearer

Simple Analogy: Imagine you're in a classroom. When you say "this classroom," you're pointing to the room you're currently in. Similarly, 'this' points to the current object you're working with in code.

Uses of 'this' Keyword

1. Differentiate Instance Variables from Parameters

When parameter names are the same as instance variable names, 'this' helps distinguish between them.

Example: this.name = name; - Left side is the instance variable, right side is the parameter

2. Call Current Class Methods

You can use 'this' to explicitly call methods of the current class, though it's optional in most cases.

Example: this.display(); - Calls the display method of the current object

3. Call Current Class Constructor

Use this() to call another constructor of the same class (constructor chaining).

Example: this(name, age); - Calls another constructor with parameters

4. Pass Current Object as Parameter

You can pass the current object to methods or constructors using 'this'.

Example: processObject(this); - Passes the current object

5. Return Current Object

Methods can return the current object using 'this', useful for method chaining.

Example: return this; - Returns the current object

'this' with Instance Variables

The most common use of 'this' is to distinguish between instance variables and parameters with the same name.

Example: Using 'this' to Avoid Naming Conflicts

class Student {
    String name;
    int age;
    String course;
    
    // Constructor with parameters having same names as instance variables
    Student(String name, int age, String course) {
        this.name = name;      // this.name = instance variable
        this.age = age;        // name = parameter
        this.course = course;
    }
    
    void setDetails(String name, int age) {
        this.name = name;      // Using 'this' to set instance variable
        this.age = age;
    }
    
    void display() {
        System.out.println("Name: " + this.name);
        System.out.println("Age: " + this.age);
        System.out.println("Course: " + this.course);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("Alice", 20, "Computer Science");
        s1.display();
        
        s1.setDetails("Alice Johnson", 21);
        s1.display();
    }
}
Output:
Name: Alice
Age: 20
Course: Computer Science
-------------------
Name: Alice Johnson
Age: 21
Course: Computer Science
-------------------

Explanation:

  • this.name refers to the instance variable of the class
  • name (without this) refers to the method parameter
  • Without 'this', Java would use the parameter and ignore the instance variable
  • Using 'this' makes the code clear and prevents bugs

Using 'this()' for Constructor Chaining

You can call one constructor from another constructor using this(). This is called constructor chaining and helps reduce code duplication.

Example: Constructor Chaining with 'this()'

class Employee {
    String name;
    int id;
    double salary;
    String department;
    
    // Constructor 1: All parameters
    Employee(String name, int id, double salary, String department) {
        this.name = name;
        this.id = id;
        this.salary = salary;
        this.department = department;
    }
    
    // Constructor 2: Calls Constructor 1 with default department
    Employee(String name, int id, double salary) {
        this(name, id, salary, "General");  // Calls first constructor
    }
    
    // Constructor 3: Calls Constructor 2 with default salary
    Employee(String name, int id) {
        this(name, id, 30000.0);  // Calls second constructor
    }
    
    void display() {
        System.out.println("ID: " + id + ", Name: " + name);
        System.out.println("Salary: $" + salary + ", Department: " + department);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        Employee emp1 = new Employee("John", 101, 50000, "IT");
        Employee emp2 = new Employee("Sarah", 102, 45000);
        Employee emp3 = new Employee("Mike", 103);
        
        emp1.display();
        emp2.display();
        emp3.display();
    }
}
Output:
ID: 101, Name: John
Salary: $50000.0, Department: IT
-------------------
ID: 102, Name: Sarah
Salary: $45000.0, Department: General
-------------------
ID: 103, Name: Mike
Salary: $30000.0, Department: General
-------------------

Explanation:

  • this(name, id, salary, "General") calls the first constructor from the second constructor
  • Constructor chaining must be the first statement in the constructor
  • Reduces code duplication by reusing initialization logic
  • Each constructor adds default values for missing parameters

Important Rule: The this() call must be the FIRST statement in a constructor. You cannot write any other code before it!

What is the 'super' Keyword?

The 'super' keyword is a reference variable that refers to the immediate parent class object. It's used in inheritance to access parent class members.

Think of 'super' as a way to reach up to your parent. Just like you might ask your parents for help or use their things, 'super' lets a child class access its parent class's properties and methods.

  • super refers to the immediate parent class object
  • Used to access parent class variables, methods, and constructors
  • Helpful when child class has members with the same name as parent class
  • Essential for calling parent class constructors from child class

Key Difference: 'this' = current class | 'super' = parent class. Use 'this' to refer to yourself, use 'super' to refer to your parent.

Uses of 'super' Keyword

1. Access Parent Class Variables

When child and parent classes have variables with the same name, use 'super' to access the parent's variable.

Example: super.salary - Accesses parent class's salary variable

2. Call Parent Class Methods

Use 'super' to call methods from the parent class, especially when the child class overrides them.

Example: super.display(); - Calls parent class's display method

3. Call Parent Class Constructor

Use super() to call the parent class constructor from the child class constructor.

Example: super(name, age); - Calls parent constructor with parameters

'super' to Access Parent Class Variables

When both parent and child classes have variables with the same name, use 'super' to access the parent's variable.

Example: Accessing Parent Class Variables

class Vehicle {
    int maxSpeed = 120;
    
    void showSpeed() {
        System.out.println("Vehicle max speed: " + maxSpeed + " km/h");
    }
}

class Car extends Vehicle {
    int maxSpeed = 180;  // Same variable name as parent
    
    void displaySpeeds() {
        System.out.println("Car's max speed: " + maxSpeed + " km/h");
        System.out.println("Parent Vehicle's max speed: " + super.maxSpeed + " km/h");
        
        // Calling parent method
        super.showSpeed();
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car();
        myCar.displaySpeeds();
    }
}
Output:
Car's max speed: 180 km/h
Parent Vehicle's max speed: 120 km/h
Vehicle max speed: 120 km/h

Explanation:

  • maxSpeed refers to Car's variable (180)
  • super.maxSpeed refers to Vehicle's variable (120)
  • super.showSpeed() calls the parent class's method
  • Without 'super', you can only access the child class's variable

'super' to Call Parent Class Methods

When a child class overrides a parent class method, you can still call the parent's version using 'super'.

Example: Calling Parent Class Methods

class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
    
    void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Dog barks");
    }
    
    void makeSound() {
        sound();         // Calls Dog's sound() method
        super.sound();   // Calls Animal's sound() method
    }
    
    void dogEat() {
        super.eat();     // Calls parent's eat() method
        System.out.println("Dog is eating bones");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        
        System.out.println("--- Making Sounds ---");
        myDog.makeSound();
        
        System.out.println("\n--- Eating ---");
        myDog.dogEat();
    }
}
Output:
--- Making Sounds ---
Dog barks
Animal makes a sound

--- Eating ---
Animal is eating
Dog is eating bones

Explanation:

  • sound() calls the Dog's overridden method
  • super.sound() calls the original Animal's method
  • super.eat() calls the parent's eat method before adding dog-specific behavior
  • This is useful when you want to extend parent functionality, not replace it

Using 'super()' to Call Parent Constructor

Use super() to call the parent class constructor from the child class constructor. This ensures the parent class is properly initialized.

Example: Calling Parent Constructor with 'super()'

class Person {
    String name;
    int age;
    
    // Parent class constructor
    Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person constructor called");
    }
    
    void displayPersonInfo() {
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
    }
}

class Student extends Person {
    String studentId;
    String course;
    
    // Child class constructor
    Student(String name, int age, String studentId, String course) {
        super(name, age);  // Calls parent constructor
        this.studentId = studentId;
        this.course = course;
        System.out.println("Student constructor called");
    }
    
    void displayStudentInfo() {
        super.displayPersonInfo();  // Calls parent method
        System.out.println("Student ID: " + studentId);
        System.out.println("Course: " + course);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("Alice", 20, "S101", "Computer Science");
        s1.displayStudentInfo();
        
        Student s2 = new Student("Bob", 22, "S102", "Mathematics");
        s2.displayStudentInfo();
    }
}
Output:
Person constructor called
Student constructor called
Name: Alice
Age: 20
Student ID: S101
Course: Computer Science
-------------------
Person constructor called
Student constructor called
Name: Bob
Age: 22
Student ID: S102
Course: Mathematics
-------------------

Explanation:

  • super(name, age) calls the Person constructor with two parameters
  • The parent constructor executes first, then the child constructor continues
  • super() must be the first statement in the child constructor
  • If you don't call super() explicitly, Java automatically calls the parent's no-arg constructor

Important Note: If the parent class doesn't have a no-argument constructor, you MUST explicitly call super() with the required parameters in the child class constructor.

'this' vs 'super' - Key Differences

Here's a quick comparison to understand when to use 'this' and when to use 'super':

Example: Using Both 'this' and 'super' Together

class Parent {
    String name = "Parent";
    
    Parent() {
        System.out.println("Parent constructor");
    }
    
    void display() {
        System.out.println("Parent display method");
    }
}

class Child extends Parent {
    String name = "Child";
    
    Child() {
        super();  // Calls parent constructor
        System.out.println("Child constructor");
    }
    
    void show() {
        String name = "Local";
        
        System.out.println("Local variable: " + name);           // Local variable
        System.out.println("Current class variable: " + this.name);  // Child's name
        System.out.println("Parent class variable: " + super.name);  // Parent's name
        
        this.display();   // Calls Child's display (if overridden)
        super.display();  // Calls Parent's display
    }
    
    void display() {
        System.out.println("Child display method");
    }
}

public class Main {
    public static void main(String[] args) {
        Child obj = new Child();
        System.out.println("-------------------");
        obj.show();
    }
}
Output:
Parent constructor
Child constructor
-------------------
Local variable: Local
Current class variable: Child
Parent class variable: Parent
Child display method
Parent display method

Explanation:

  • name - refers to the local variable
  • this.name - refers to Child class's instance variable
  • super.name - refers to Parent class's instance variable
  • this.display() - calls Child's method
  • super.display() - calls Parent's method

Quick Comparison: 'this' vs 'super'

  • this: Refers to current class object | super: Refers to parent class object
  • this: Accesses current class variables/methods | super: Accesses parent class variables/methods
  • this(): Calls current class constructor | super(): Calls parent class constructor
  • this: Used within the same class | super: Used in inheritance (child class)
  • this: Can be used without inheritance | super: Requires inheritance to work

Memory Tip: 'this' = ME (current object) | 'super' = MY PARENT (parent object). Use 'this' when talking about yourself, use 'super' when talking about your parent!

Important Rules to Remember

  • First Statement Rule: Both this() and super() must be the first statement in a constructor
  • Cannot Use Both: You cannot use both this() and super() in the same constructor (only one can be first!)
  • Implicit super(): If you don't call super() explicitly, Java automatically adds super() as the first line
  • this with Methods: this can be used in any method, not just constructors
  • super in Child Only: super keyword only works in child classes that extend a parent class
  • Static Context: Neither this nor super can be used in static methods (static methods don't belong to objects)

Common Mistake: Trying to use both this() and super() in the same constructor will give a compilation error because only one can be the first statement!

Key Takeaways

  • 'this' keyword: References the current class object
  • 'super' keyword: References the immediate parent class object
  • Variable Access: Use 'this' for current class variables, 'super' for parent class variables
  • Method Calls: Use 'this' for current class methods, 'super' for parent class methods
  • Constructor Chaining: Use this() to call another constructor in the same class
  • Parent Constructor: Use super() to call parent class constructor
  • First Statement: Both this() and super() must be the first statement in constructors

Practice Challenge: Create a "Shape" parent class with properties like color and area. Then create "Circle" and "Rectangle" child classes. Use 'super' to access parent properties and 'this' to distinguish between local and instance variables. Try method overriding and calling parent methods using 'super'!