Từ Khóa: this (This Keywords)

"Trong Java, từ khóa this là một công cụ mạnh mẽ trong lập trình hướng đối tượng, giúp giải quyết xung đột giữa các biến và làm cho mã nguồn trở nên rõ ràng hơn. Dưới đây là những điều cơ bản bạn cần biết về từ khóa this trong Java."

Từ khóa this trong Java được sử dụng để tham chiếu đến đối tượng của lớp hiện tại. Bằng cách sử dụng this, bạn có thể truy cập và thao tác với các thành phần của đối tượng đó như biến, phương thức, constructor và thậm chí là lớp lồng nhau. Việc này giúp cho mã nguồn trở nên rõ ràng hơn trong việc xử lý các tên biến trùng lặp (shadowing), gọi constructor từ constructor khác của cùng lớp, và quản lý phạm vi của các thành phần lớp.

Trong java, từ khóa this có 6 cách sử dụng như sau:

Từ khóa this có thể được dùng để truy cập tới biến instance của lớp hiện tại.

Từ khóa this có thể được dùng để gọi phương thức của lớp hiện tại.

Từ khóa this() có thể được dùng để gọi Constructor của lớp hiện tại.

Từ khóa this có thể được truyền như một tham số trong phương thức.

Từ khóa this có thể được truyền như một tham số trong phương Constructor.

Từ khóa this có thể được dùng để trả về instance của lớp hiện tại.

Lưu ý:

Trong lập trình, đặc biệt là lập trình hướng đối tượng (OOP), instance (hay còn gọi là thể hiện, đối tượng cụ thể) là một bản sao riêng biệt và không trùng lặp của một lớp (class). Lớp đóng vai trò như bản thiết kế, bản mẫu, trong khi instance là hiện thân thực tế của bản thiết kế đó. Ví dụ, nếu bạn có một lớp Car, thì khi bạn tạo một đối tượng Car, ví dụ Car myCar = new Car();, myCar là một thể hiện (instance) của lớp Car.

Các chức năng của từ khóa this
Ảnh mô tả các chức năng của từ khóa this.

Ⅰ. Từ khóa this dùng để truy cập tới biến instance của lớp hiện tại.

Từ khóa this được dùng để tham chiếu đến biến instance (còn gọi là thuộc tính) của đối tượng hiện tại. Nó hữu ích trong trường hợp tên biến instance trùng với tên tham số của phương thức.

Trong ví dụ, có khả năng xảy ra nhầm lẫn

↳ Biến name được khai báo bên trong lớp (biến instance).

↳ Tham số name được truyền vào phương thức (tham số).

Nếu không dùng this, compiler (trình biên dịch) sẽ khó xác định bạn muốn sử dụng biến instance name hay tham số name.

Ví dụ: Point.java

// Định nghĩa lớp Point với hai thuộc tính x và y
public class Point {
    public int x = 0; // Biến instance 'x'
    public int y = 0; // Biến instance 'y'

    // Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho x và y
    public Point(int x, int y) { // Tham số 'x' và 'y'
        x = x; // Không dùng this
        y = y;
    }
    public void display() {
        System.out.println("Toạ độ điểm x= "+ x + ", y= "+y);
    }
    public static void main(String args[]) {
        Point point1 = new Point(50, 50);
        Point point2 = new Point(100, 100);
        point1.display();
        point2.display();  
    }
}

Kết quả của chương trình là:

Toạ độ điểm x= 0, y= 0
Toạ độ điểm x= 0, y= 0

Sử dụng this giải quyết vấn đề

Bằng cách sử dụng this.Tên_Biến trước tên biến instance, bạn rõ ràng chỉ ra cho compiler rằng bạn muốn truy cập vào biến instance name thuộc về đối tượng hiện tại.

Ví dụ: Point.java

// Định nghĩa lớp Point với hai thuộc tính x và y
public class Point {
    public int x = 0; // Biến instance 'x'
    public int y = 0;// Biến instance 'y'

    // Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho x và y
    public Point(int x, int y) {// Tham số 'x và y'
        this.x = x; // Dùng từ khóa this
        this.y = y;
    }
    public void display() {
        System.out.println("Toạ độ điểm x= "+ x + ", y= "+y);
    }
    public static void main(String args[]) {
        Point point1 = new Point(50, 50);
        Point point2 = new Point(100, 100);
        point1.display();
        point2.display();
    }
}

Kết quả của chương trình là:

Toạ độ điểm x= 50, y= 50
Toạ độ điểm x= 100, y= 100

Gán giá trị để giải quyết vấn đề:

Ví dụ: Point.java

// Định nghĩa lớp Point với hai thuộc tính x và y
public class Point {
    public int x = 0; // Biến instance 'x'
    public int y = 0;// Biến instance 'y'

    // Constructor của lớp Point, nhận vào hai tham số int và gán giá trị cho n và m
    public Point(int n, int m) {
         x = n; // Không cần phải sử dụng this vì tên không trùng
         y = m;
    }
    public void display() {
        System.out.println("Toạ độ điểm x= "+ x + ", y= "+ y);
    }
    public static void main(String args[]) {
        Point point1 = new Point(50, 50);
        Point point2 = new Point(100, 100);
        point1.display();
        point2.display();
    }
}

Kết quả của chương trình là:

Toạ độ điểm x= 50, y= 50
Toạ độ điểm x= 100, y= 100

Ⅱ. Từ khóa this dùng để gọi phương thức của lớp hiện tại.

Từ khóa this trong Java không chỉ dùng để truy cập biến instance mà còn có thể gọi các phương thức (method) của lớp hiện tại. Việc sử dụng this làm rõ ràng bạn đang gọi phương thức của lớp hiện tại, tránh nhầm lẫn với phương thức của lớp khác. Bằng cách sử dụng this.Tên_Phương thức trước tên phương thức (Methods) và tham số của phương thức nếu có.

Ví dụ: Person.java

class Person {
    String name; // Biến instance 'name' để lưu tên của đối tượng Person

    // Constructor của lớp Person, nhận một tham số là tên và gán nó cho biến 'name'
    public Person(String name) {
        this.name = name;
    }

    // Phương thức greet() để in ra lời chào kèm theo tên của đối tượng
    public void greet() {
        System.out.println("Xin chào, tên của tôi là: " + this.name);
    }

    // Phương thức introduce() để gọi phương thức greet()
    public void introduce() {
        this.greet(); // Gọi phương thức 'greet()' của lớp hiện tại
    }

    // Phương thức main để chạy chương trình
    public static void main(String[] args) {
        // Tạo một đối tượng Person với tên "VTD"
        Person person = new Person("VTD");
        // Gọi phương thức introduce() của đối tượng person
        person.introduce();
    }
}

Kết quả của chương trình là:

Xin chào, tên của tôi là: VTD

Trong phương thức introduce(), từ khóa this được sử dụng để gọi các phương thức greet() của đối tượng hiện tại. Điều này làm cho code trở nên rõ ràng và dễ đọc hơn, cho thấy rằng các phương thức này thuộc về đối tượng hiện tại của lớp Person.

Trong nhiều trường hợp, nếu bạn không sử dụng từ khóa this để gọi một phương thức của lớp hiện tại, trình biên dịch Java sẽ tự động thêm nó cho bạn. Điều này có nghĩa là việc gọi một phương thức mà không có từ khóa this sẽ hoạt động tương tự như khi bạn gọi phương thức đó với từ khóa this.

Ví dụ: Person.java

/class Person {
    String name; // Biến instance 'name' để lưu tên của đối tượng Person

    // Constructor của lớp Person, nhận một tham số là tên và gán nó cho biến 'name'
    public Person(String name) {
        this.name = name;
    }

    // Phương thức greet() để in ra lời chào kèm theo tên của đối tượng
    public void greet() {
        System.out.println("Xin chào, tên của tôi là: " + this.name);
    }
    public void Support() {
        System.out.println("Tôi có thể giúp gì được cho bạn " );
    }

    // Phương thức introduce() để gọi phương thức greet() và  Support() của lớp hiện tại
    public void introduce() {
        greet(); // Không dùng từ khóa this
        Support();
    }

    // Phương thức main để chạy chương trình
    public static void main(String[] args) {
        // Tạo một đối tượng Person với tên "VTD"
        Person person = new Person("VTD");
        // Gọi phương thức introduce() của đối tượng person
        person.introduce();
    }
}

Kết quả của chương trình là:

Xin chào, tên của tôi là: VTD
Tôi có thể giúp gì được cho bạn

Trong ví dụ trên, trình biên dịch sẽ tự động hiểu rằng các phương thức này thuộc về đối tượng hiện tại và thêm từ khóa this một cách ngầm định.

Trình biên dịch thêm từ khóa this một cách ngầm định
Ảnh mô tả trình biên dịch sẽ thêm từ khóa this một cách ngầm định.

Ⅲ. Từ khóa this() dùng để gọi constructor của lớp hiện tại.

từ khóa this() được sử dụng để gọi một constructor khác trong cùng một lớp. this() chỉ được phép xuất hiện duy nhất một lần và luôn phải là câu lệnh đầu tiên được viết trong constructor. Cú pháp của nó như sau: this(tham số của constructor).

Ví dụ: Person.java

public class Person {
    // Các biến instance để lưu tên và tuổi của đối tượng Person
    private String name;
    private int age;

    // Constructor mặc định, không có tham số
    public Person() {
        this("Constructor mặc định", 0); // Gọi constructor có hai tham số với giá trị mặc định
    }

    // Constructor với một tham số, chỉ định tên
    public Person(String name) {
        this(name, 1); // Gọi constructor có hai tham số, với tuổi mặc định là 1
    }

    // Constructor với hai tham số, chỉ định cả tên và tuổi
    public Person(String name, int age) {
        this.name = name;
        this.age = age; // Gán giá trị tham số cho các biến instance
    }

    // Phương thức display() để in ra tên và tuổi của đối tượng
    public void display() {
        System.out.println("Tên: " + name + ", Tuổi: " + age);
    }

    // Phương thức main để chạy chương trình
    public static void main(String[] args) {
        // Tạo các đối tượng Person với các constructor khác nhau
        Person person1 = new Person(); // Sử dụng constructor mặc định
        Person person2 = new Person("Constructor với một tham số"); // Sử dụng constructor với một tham số
        Person person3 = new Person("Constructor với hai tham số", 2); // Sử dụng constructor với hai tham số

        // Gọi phương thức display() của từng đối tượng để in ra thông tin
        person1.display();
        person2.display();
        person3.display();
    }
}

Kết quả của chương trình là:

Tên: Constructor mặc định, Tuổi: 0
Tên: Constructor với một tham số, Tuổi: 1
Tên: Constructor với hai tham số, Tuổi: 2

Trong ví dụ này, việc sử dụng từ khóa this() giúp tránh lặp lại mã và thiết lập các giá trị mặc định cho các biến thành viên một cách hiệu quả.

Ⅳ. Từ khóa this được truyền như một tham số trong phương thức.

từ khóa this có thể được truyền như một tham số cho các phương thức khác. Việc sử dụng này ít phổ biến hơn so với các trường hợp sử dụng this khác, nhưng nó có thể hữu ích trong một số tình huống cụ thể. Cú pháp của nó như sau: Tên_Phươngthức(this).

Ví dụ: Student.java

class Student {
    int id; // Biến instance 'id' để lưu mã số sinh viên
    String name; // Biến instance 'name' để lưu tên của sinh viên

    // Constructor của lớp Student, nhận hai tham số và gán chúng cho các biến instance
    Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    // Phương thức display() để in ra mã số sinh viên và tên sinh viên
    void display() {
        System.out.println("Mã: " + id + ", Tên: " + name);
    }

    // Phương thức updateName() để cập nhật tên của đối tượng Student được truyền vào
    void updateName(Student student, String newName) {
        student.name = newName;
    }

    // Phương thức changeName() để thay đổi tên của đối tượng hiện tại
    void changeName(String newName) {
        updateName(this, newName); // Gọi phương thức updateName() với đối tượng hiện tại
    }

    // Phương thức main để chạy chương trình
    public static void main(String[] args) {
        // Tạo một đối tượng Student với mã số 1 và tên "Vương"
        Student student = new Student(1, "Vương");
        // Gọi phương thức display() để in ra thông tin sinh viên
        student.display(); // Kết quả: ID: 1, Name: Vương

        // Gọi phương thức changeName() để thay đổi tên của sinh viên thành "Trường"
        student.changeName("Trường");
        // Gọi phương thức display() để in ra thông tin sinh viên đã cập nhật
        student.display(); // Kết quả: ID: 1, Name: Trường
    }
}

Kết quả của chương trình là:

Mã: 1, Tên: Vương
Mã: 1, Tên: Trường

Hy vọng ví dụ này giúp bạn hiểu rõ hơn về việc sử dụng từ khóa this được truyền như một tham số trong phương thức!

Ⅴ. Từ khóa this được truyền như một tham số trong constructor.

Trong một số trường hợp hiếm hoi, bạn có thể truyền this (đối tượng hiện tại) làm tham số cho một constructor khác. Có nghĩa là bạn đang chuyển đối tượng hiện tại của lớp đó vào constructor của một lớp khác. Điều này có thể hữu ích khi bạn cần chia sẻ dữ liệu hoặc hành động giữa các đối tượng liên quan. Cú pháp của nó như sau: this.Tên_đốitượng.

Ví dụ: Person.java

// Định nghĩa lớp Person để biểu diễn một người có tên và tuổi
class Person {
    String name; // Biến instance lưu trữ tên của người
    int age; // Biến instance lưu trữ tuổi của người

    // Constructor của lớp Person, nhận tham số là tên và tuổi, và gán cho các biến instance tương ứng
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Phương thức displayInfo() in ra thông tin tên và tuổi của người
    void displayInfo() {
        System.out.println("Tên: " + name);
        System.out.println("Tuổi: " + age);
    }
}

// Định nghĩa lớp Address để biểu diễn địa chỉ có thành phố, quốc gia và một đối tượng Person
class Address {
    String city; // Biến instance lưu trữ tên thành phố
    String country; // Biến instance lưu trữ tên quốc gia
    Person person; // Biến instance lưu trữ thông tin của một đối tượng Person

    // Constructor của lớp Address, nhận tham số là thành phố, quốc gia và một đối tượng Person, và gán cho các biến instance tương ứng
    Address(String city, String country, Person person) {
        this.city = city;
        this.country = country;
        this.person = person;
    }

    // Phương thức displayAddress() in ra thông tin của đối tượng Person và địa chỉ
    void displayAddress() {
        person.displayInfo(); // Gọi phương thức displayInfo() của đối tượng Person để in ra thông tin tên và tuổi
        System.out.println("Thành Phố: " + city); // In ra tên thành phố
        System.out.println("Quốc Gia: " + country); // In ra tên quốc gia
    }
}

// Lớp chính MainClass để chạy chương trình
public class MainClass {
    public static void main(String[] args) {
        Person person = new Person("Vương", 27); 
        Address address = new Address("Đà Nẵng", "Việt Nam", person); 
        address.displayAddress(); // Gọi phương thức displayAddress() của đối tượng Address để in ra thông tin địa chỉ và đối tượng Person
    }
}

Kết quả của chương trình là:

Tên: Vương
Tuổi: 27
Thành Phố: Đà Nẵng
Quốc Gia: Việt Nam

Trong ví dụ này, từ khóa this được sử dụng để truyền đối tượng hiện tại vào constructor hoặc phương thức khác, giúp chia sẻ thông tin giữa các đối tượng một cách dễ dàng.

Ⅵ. Từ khóa this được dùng để trả về instance của lớp hiện tại.

Khi bạn sử dụng this để trả về thể hiện của lớp hiện tại, có nghĩa là bạn đang yêu cầu Java trả về đối tượng đang thực thi phương thức hiện tại. Điều này thường được sử dụng trong các phương thức để trả về chính đối tượng mà phương thức đang thao tác. Cú pháp của nó như sau:

Cú Pháp

Kiểu_trảvề Tên_Phươngthức(){

    return this;
}

Ví dụ: Book.java

public class Book {
    private String title; // Biến instance để lưu trữ tiêu đề sách
    private String author; // Biến instance để lưu trữ tác giả của sách

    // Constructor của lớp Book, khởi tạo đối tượng Book với tiêu đề và tác giả
    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    // Phương thức setTitle để thay đổi tiêu đề sách
    public void setTitle(String newTitle) {
        this.title = newTitle;
    }

    // Phương thức getCurrentBook trả về chính đối tượng Book hiện tại
    public Book getCurrentBook() {
        return this;
    }

    // Phương thức displayInfo để hiển thị thông tin của cuốn sách
    public void displayInfo() {
        System.out.println("Tiêu đề: " + title);
        System.out.println("Tác giả: " + author);
    }

    // Phương thức main để chạy chương trình
    public static void main(String[] args) {
        // Tạo một đối tượng Book mới với tiêu đề "Lập trình java" và tác giả "Java"
        Book myBook = new Book("Lập trình java", "Java");

        // Đặt lại tiêu đề của sách
        myBook.setTitle("Lập trình hướng đối tượng trong Java");

        // Lấy đối tượng Book hiện tại thông qua phương thức getCurrentBook()
        Book currentBook = myBook.getCurrentBook();

        // In ra thông tin của cuốn sách hiện tại
        System.out.println("Thông tin cuốn sách hiện tại:");
        currentBook.displayInfo();
    }
}

Kết quả của chương trình là:

Thông tin cuốn sách hiện tại:
Tiêu đề: Lập trình hướng đối tượng trong Java
Tác giả: Java

Trong ví dụ này, khi chạy chương trình chúng ta thấy rằng việc sử dụng this trong phương thức getCurrentBook() đã giúp chúng ta trả về đúng thể hiện (instance) của lớp Book hiện tại mà phương thức đang hoạt động.

Lưu ý:

this chỉ có thể được sử dụng để trả về instance của lớp hiện tại từ một phương thức instance.

Chứng minh từ khóa this

Hãy chứng minh rằng từ khóa this tham chiếu đến biến instance của lớp hiện tại. Trong chương trình này, chúng ta đang in ra biến tham chiếu và this, đầu ra của cả hai biến đều giống nhau.

Ví dụ: Book.java

public class Book {
    private String title; // Biến private để lưu trữ tiêu đề của sách

    // Constructor của lớp Book, nhận một tham số là tiêu đề và gán nó cho biến 'title'
    public Book(String title) {
        this.title = title;
    }

    // Phương thức printCurrentBook() để in ra thông tin về cuốn sách hiện tại
    public void printCurrentBook() {
        System.out.println("Cuốn sách hiện tại: " + this.title);
    }

    // Phương thức main để chạy chương trình
    public static void main(String[] args) {
        // Tạo một đối tượng Book với tiêu đề "Lập trình Java"
        Book book1 = new Book("Lập trình Java");
        // Gọi phương thức printCurrentBook() của đối tượng book1
        book1.printCurrentBook();

        // Tạo một đối tượng Book với tiêu đề "Cấu trúc dữ liệu"
        Book book2 = new Book("Cấu trúc dữ liệu");
        // Gọi phương thức printCurrentBook() của đối tượng book2
        book2.printCurrentBook();
    }
}

Kết quả của chương trình là:

Cuốn sách hiện tại: Lập trình Java
Cuốn sách hiện tại: Cấu trúc dữ liệu

Trong ví dụ này, từ khóa this được sử dụng để chỉ rõ rằng title được truy cập là của đối tượng hiện tại mà phương thức printCurrentBook() đang thao tác.

Câu Nói Truyền Cảm Hứng

“Bắt đầu ở đâu không quan trọng, quan trọng là bạn sẵn sàng bắt đầu.” – W. Clement Stone

Không Gian Tích Cực

“Chúc bạn luôn giữ vững niềm tin và sức mạnh để vượt qua mọi thử thách trong cuộc sống.”