1. Từ khóa Super trong Java

Từ khóa super trong Java là một biến tham chiếu được sử dụng trực tiếp để tham chiếu đến đối tượng của lớp cha gần nhất. Ta có thể sử dụng nếu lớp cha và con có cùng các trường.

  • Giúp gọi phương thức của lớp cha được ghi đè(overriding) trong lớp con
  • Giúp truy cập các thuộc tính của lớp cha nếu như cả lớp con và lớp cha có các thuộc tính giống tên nhau
  • Giúp gọi hàm khởi tạo có tham số hoặc không có tham số của lớp cha

Bất cứ khi nào bạn tạo ra instance (thể hiện) của lớp con, một instance của lớp cha được tạo ra ngầm định, nghĩa là được tham chiếu bởi biến super. Ta cũng có thể dùng super để tham chiếu tới một trường ẩn nào đó(không khuyến khích) của lớp cha.

2. Dùng super gọi phương thức của lớp cha

Nếu các phương thức cùng tên được định nghĩa trong cả superclasssubclass, phương thức trong subclass sẽ ghi đè lên phương thức trong super class. Đây được gọi là ghi đè phương thức trong Java.

Khi lớp con gọi phương thức ghi đè có cùng tên với phương thức của lớp cha thì phương thức được gọi đó là của lớp con.

Từ khóa super cũng có thể được sử dụng để gọi phương thức của lớp cha. Nó nên được sử dụng trong trường hợp lớp chứa các phương thức tương tự như lớp cha

Ví dụ:

class Person {
    void message() {
        System.out.println("lập trình từ đầu");
    }
}
 
public class Main extends Person {
    void message() {
        System.out.println("welcome to java");
    }
 
    void display() {
        message();// gọi phương thức message() của lớp hiện tại
        super.message();// gọi phương thức message() của lớp cha
    }
 
    public static void main(String args[]) {
        Main s = new Main();
        s.display();
    }
}

Kết quả

welcome to java
lập trình từ đầu

Trong ví dụ trên cả hai lớp MainPerson đều có phương thức message(). Nếu ta gọi phương thức message() từ lớp Main thì phương thức message của Main sẽ đươc thực thi vì phương thức ở local sẽ được ưu tiên.

Nếu như phương thức của lớp cha khác tên phương thức của lớp con thì chúng ta không cần phải dùng từ khóa super.

Ví dụ:

class Person {
    void message() {
        System.out.println("Lập trình từ đầu");
    }
}
 
public class Main extends Person {
 
    void display() {
        message();// gọi phương thức message() của lớp cha
    }
 
    public static void main(String args[]) {
        Main s = new Main();
        s.display();
    }
}

Kết quả

Lập trình từ đầu

3. Dùng super truy cập thuộc tính của lớp cha

Lớp cha và lớp con có thể có các thuộc tính có tên giống nhau. Vì vậy, ta có thể dùng super để gọi đến thuộc tính của lớp cha.

Ví dụ:

class LopCha{
    protected String type="LopCha.";
}
class LopCon extends LopCha{
    public String type="LopCon.";
    public void xuat(){
        System.out.println(type);
        //gọi thuộc tính lớp cha
        System.out.println(super.type);
    }
}
public class Main{
    public static void main(String[] args) {
        LopCon aaa = new LopCon();
        aaa.xuat();
    }
}

Kết quả

LopCon.
LopCha.

4. Dùng super truy cập hàm khởi tạo của lớp cha

Khi một đối tượng của lớp con được tạo ra, hàm khởi tạo mặc định(default constructor) của lớp cha sẽ tự động được gọi. Trong một số trường hợp, chúng ta muốn chọn hàm khởi tạo nào trong lớp cha được gọi thì có thể sử dụng super().

Trong hàm khởi tạo của lớp con, chúng ta có thể gọi hàm khởi tạo của lớp cha bằng super(). Ta chỉ có thể gọi super() trong hàm khởi tạo của lớp con và phải được đặt ở dòng lệnh đầu tiên trong hàm khởi tạo của lớp con.

Ví dụ:

class Ja {
    Ja() {
        System.out.println("Học Java");
    }
}

class Main extends Ja {
    Main() {
        super();// gọi Constructor của lớp cha
        System.out.println("Tại laptrinhtudau.com");
    }

    public static void main(String args[]) {
        Main b = new Main();
    }
}

Kết quả

Học Java
Tại laptrinhtudau.com

Như chúng ta đã biết Constructor được tạo ra tự động bởi trình biên dịch nhưng nó cũng thêm super() vào câu lệnh đầu tiên. Nếu ta tạo Constructor và bạn không có this() hoặc super() ở dòng lệnh đầu tiên, trình biên dịch sẽ cung cấp super() của Constructor.

Chú ý

Ta không thể dùng từ khóa này để chỉ các lớp ông, cụ, …. Ví dụ như việc viết super.super.add(1,5); là sai!

class Ja {
    Ja() {
        System.out.println("Học Java");
    }
}

public class Main extends Ja {
    int speed;

    Main(int speed) {
        this.speed = speed;
        System.out.println(speed);
    }

    public static void main(String args[]) {
        Main b = new Main(100);
    }
}

Kết quả

Học Java
100

Nếu đã gọi hàm khởi tạo có tham số của lớp cha trong lớp con thì hàm khởi tạo mặc định của lớp cha sẽ không được trình biên dịch tự gọi nữa.