The super and this keywords in Java are used to refer to parent class members and current class members, respectively. They play crucial roles in inheritance, method overriding, and object-oriented design.

this Keyword

The this keyword refers to the current object of the class. It is commonly used to avoid naming conflicts and to access class-level members when local variables have the same name.

Common Uses of this

1. To refer to instance variables: Resolves conflicts between instance variables and method/local variables with the same name.

class Example {
    int x;

    Example(int x) {
        this.x = x; // Resolves ambiguity
    }
}

2. To invoke current class methods: Calls a method of the current class.

class Example {
    void display() {
        System.out.println("Display method called.");
    }

    void callDisplay() {
        this.display(); // Optional, as 'display()' would work too
    }
}

3. To invoke current class constructors: Used for constructor chaining within the same class.

class Example {
    Example() {
        this("Default constructor");
    }

    Example(String message) {
        System.out.println(message);
    }
}

4. To pass the current object as an argument:

class Example {
    void show(Example obj) {
        System.out.println("Method called with object: " + obj);
    }

    void call() {
        show(this); // Passing the current object
    }
}

super Keyword

The super keyword refers to the parent class (immediate superclass) of the current class. It is primarily used in inheritance to access parent class members or constructors.

Common Uses of super

1. To call the parent class constructor: The super() statement must be the first line in a constructor. If omitted, the compiler inserts a default super() call to the no-argument constructor of the parent class.

class Parent {
    Parent(String msg) {
        System.out.println("Parent constructor: " + msg);
    }
}

class Child extends Parent {
    Child() {
        super("Called from Child"); // Calls Parent's constructor
    }
}

2. To access parent class methods: Calls an overridden method in the parent class.

class Parent {
    void display() {
        System.out.println("Parent class display method");
    }
}

class Child extends Parent {
    @Override
    void display() {
        super.display(); // Calls Parent's display method
        System.out.println("Child class display method");
    }
}

3. To access parent class fields: Accesses fields of the parent class when they are hidden by child class fields.

class Parent {
    int x = 10;
}

class Child extends Parent {
    int x = 20;

    void printValues() {
        System.out.println("Parent's x: " + super.x); // Access parent class field
        System.out.println("Child's x: " + this.x);  // Access child class field
    }
}

Examples

// this Example
class Demo {
    int a;

    Demo(int a) {
        this.a = a; // Resolves conflict
    }

    void display() {
        System.out.println("Value of a: " + this.a);
    }
}

public class Main {
    public static void main(String[] args) {
        Demo obj = new Demo(5);
        obj.display();
    }
}
// super Example
class Parent {
    void greet() {
        System.out.println("Hello from Parent!");
    }
}

class Child extends Parent {
    @Override
    void greet() {
        super.greet(); // Calls Parent's greet
        System.out.println("Hello from Child!");
    }
}

public class Main {
    public static void main(String[] args) {
        Child obj = new Child();
        obj.greet();
    }
}