CodeGym /Các khóa học /JAVA 25 SELF /Cấu trúc lớp: trường, phương thức, constructor

Cấu trúc lớp: trường, phương thức, constructor

JAVA 25 SELF
Mức độ , Bài học
Có sẵn

1. Trường của lớp: lưu trạng thái của đối tượng ở đâu

Trường — là một biến được khai báo bên trong lớp nhưng ngoài tất cả các phương thức. Trường đảm bảo mỗi đối tượng có “trạng thái” riêng. Ví dụ, nếu chúng ta có lớp Person, thì các trường có thể như sau:

  • name — tên người
  • age — tuổi
  • balance — số dư trong tài khoản (nếu chúng ta làm ứng dụng ngân hàng)
  • isStudent — cờ đánh dấu liệu người đó có phải là sinh viên hay không

Cú pháp khai báo trường

Khai báo trường giống như một biến thông thường, chỉ khác là nó không nằm trong phương thức mà nằm trực tiếp trong lớp:

public class Person {
    String name;
    int age;
}

Ở đây chúng ta đã khai báo hai trường: chuỗi name và số nguyên age. Mỗi trường sẽ thuộc về một đối tượng cụ thể của lớp này. Điều đó có nghĩa là các đối tượng khác nhau sẽ có giá trị khác nhau. Ví dụ:

Person p1 = new Person();
p1.name = "Olya";
p1.age = 20;

Person p2 = new Person();
p2.name = "Igor";
p2.age = 25;

Đối tượng thứ nhất có tên — “Olya” và tuổi — 20, còn đối tượng thứ hai — “Igor” và 25. Cả hai đều được tạo từ cùng một lớp, nhưng các trường của chúng lưu các dữ liệu khác nhau.

Bộ sửa đổi truy cập (public/private)

Các trường có thể là mở (public) hoặc đóng (private). Trong đời sống thực, bạn không kể số dư tài khoản ngân hàng cho mọi người, đúng không? Trong lập trình cũng vậy, người ta thường đặt các trường là private để không thể truy cập trực tiếp đến chúng từ các lớp khác. Đây là một phần của nguyên tắc đóng gói (encapsulation) — sẽ nói kỹ hơn ở các bài sau.

Ví dụ:

public class Person {
    private String name;
    private int age;
}

Tạm thời chúng ta chưa đi sâu, nhưng hãy nhớ: nếu trường là private, bạn không thể truy cập trực tiếp tới nó từ lớp khác.

2. Phương thức của lớp: đối tượng “hành động” như thế nào

Phương thức — là hàm mô tả hành vi của đối tượng. Phương thức cho phép đối tượng làm gì đó: nói, tính toán, chạy, nhảy, in thông tin về bản thân, v.v.

Cú pháp khai báo phương thức

tip_vozvrashchaemogo_znacheniya imyaMetoda(parametry) {
    // thân phương thức
}

Ví dụ phương thức nói "Xin chào":

public void sayHello() {
    System.out.println("Xin chào! Tôi tên là " + name);
}

Giải thích:

  • public — bộ sửa đổi truy cập.
  • void — phương thức không trả về gì (chỉ thực hiện hành động).
  • sayHello — tên phương thức.
  • Bên trong phương thức, chúng ta dùng trường name để chào người dùng.

Ví dụ khác: phương thức trả về tuổi

public int getAge() {
    return age;
}

Các phương thức có thể trả về giá trị (int, String, v.v.), hoặc có thể “không trả về gì” — khi đó ta dùng void.

3. Constructor: cách “sinh ra” các đối tượng

Constructor — là một phương thức đặc biệt được gọi khi tạo đối tượng mới. Nhiệm vụ của nó là khởi tạo các trường của đối tượng bằng giá trị ban đầu, tức là “lấp đầy” các “ngăn” trống của đối tượng bằng dữ liệu cụ thể. Ví dụ, đặt tên và tuổi cho người ngay tại thời điểm tạo, thay vì để trống.

  • Tên của constructor luôn trùng với tên lớp.
  • Constructor không có kiểu trả về (ngay cả void cũng không viết).
  • Constructor có thể nhận tham số (ví dụ: tên và tuổi), hoặc không có tham số.

Ví dụ constructor

public class Person {
    String name;
    int age;

    // Constructor có hai tham số
    public Person(String name, int age) {
        this.name = name; // this.name — trường của đối tượng; name — tham số của constructor
        this.age = age;
    }
}

Có lẽ bạn đang thắc mắc this là gì. Từ khóa this là tham chiếu đến chính đối tượng hiện tại. Ta dùng nó để phân biệt trường của lớp với tham số có cùng tên. Nếu không có this, trình biên dịch sẽ không biết chính xác chúng ta muốn khởi tạo cái nào.

Constructor mặc định

Nếu bạn không khai báo bất kỳ constructor nào, trình biên dịch Java sẽ tự động thêm một constructor rỗng không có tham số. Nó trông như sau:

public Person() {
    // không làm gì, nhưng cho phép tạo đối tượng không có tham số
}

Lưu ý! Nếu bạn đã khai báo ít nhất một constructor của riêng mình (ví dụ: có tham số), thì constructor mặc định sẽ không còn được tạo tự động nữa! Nếu cần — hãy viết nó một cách rõ ràng.

4. Ví dụ một lớp hoàn chỉnh

Hãy ghép tất cả lại: trường, phương thức, constructor.

public class Person {
    String name;
    int age;

    // Constructor
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Phương thức: chào hỏi
    public void sayHello() {
        System.out.println("Xin chào! Tôi tên là " + name + ", tôi " + age + " tuổi.");
    }

    // Phương thức: tăng tuổi thêm 1
    public void haveBirthday() {
        age = age + 1;
        System.out.println("Hoan hô! Bây giờ tôi " + age + " tuổi!");
    }
}

Dùng trong chương trình như thế nào?

public class Main {
    public static void main(String[] args) {
        Person vasya = new Person("Vasya", 18);
        vasya.sayHello();      // Xin chào! Tôi tên là Vasya, tôi 18 tuổi.
        vasya.haveBirthday();  // Hoan hô! Bây giờ tôi 19 tuổi!
    }
}

5. Thực hành: phát triển ứng dụng của bạn

Giả sử bạn đang làm một ứng dụng đơn giản để quản lý người dùng. Ở các bài trước, chúng ta chỉ làm việc với biến và phương thức bên trong main. Bây giờ hãy tạo lớp User của riêng bạn với các trường, phương thức và constructor.

public class User {
    String username;
    int score;

    // Constructor
    public User(String username, int score) {
        this.username = username;
        this.score = score;
    }

    // Phương thức: in thông tin về người dùng
    public void printInfo() {
        System.out.println("Tên người dùng: " + username + ", điểm: " + score);
    }

    // Phương thức: tăng điểm
    public void addScore(int points) {
        score += points;
        System.out.println(username + " đã nhận " + points + " điểm! Bây giờ cậu ấy có " + score + " điểm.");
    }
}

Cách sử dụng:

public class Main {
    public static void main(String[] args) {
        User alice = new User("Alice", 10);
        User bob = new User("Bob", 5);

        alice.printInfo(); // Tên người dùng: Alice, điểm: 10
        bob.printInfo();   // Tên người dùng: Bob, điểm: 5

        alice.addScore(7); // Alice đã nhận 7 điểm! Bây giờ cậu ấy có 17 điểm.
        bob.addScore(3);   // Bob đã nhận 3 điểm! Bây giờ cậu ấy có 8 điểm.
    }
}

Lưu ý: mỗi đối tượng có các trường riêng, và thay đổi trên một đối tượng không ảnh hưởng đến đối tượng khác.

6. Tóm tắt về bộ sửa đổi truy cập

Trong các ví dụ của chúng ta, các trường là mở (String name;). Trong thực tế, người ta thường đặt các trường là private để không thể vô tình (hoặc cố ý) thay đổi chúng từ lớp khác. Chi tiết sẽ có trong chủ đề đóng gói (encapsulation), nhưng dưới đây là ví dụ:

public class User {
    private String username;
    private int score;

    public User(String username, int score) {
        this.username = username;
        this.score = score;
    }

    public void printInfo() {
        System.out.println("Tên người dùng: " + username + ", điểm: " + score);
    }

    public void addScore(int points) {
        score += points;
    }
}

Bây giờ nếu ai đó cố gắng viết alice.score = 100500; ở ngoài lớp — trình biên dịch sẽ nói “không được!”.

7. Các lỗi thường gặp khi làm việc với trường, phương thức và constructor

Lỗi số 1: Trường chưa được khởi tạo.
Nếu bạn không gán giá trị cho các trường, chúng sẽ nhận giá trị mặc định: số — 0, booleanfalse, tham chiếu (ví dụ, String) — null. Nếu quên khởi tạo trường, bạn có thể nhận kết quả không mong muốn hoặc thậm chí NullPointerException khi cố làm gì đó với nó.

Lỗi số 2: Nhầm lẫn giữa tham số và trường.
Trong constructor, người mới thường viết đơn giản name = name; — cách này không khởi tạo trường, mà chỉ gán tham số cho chính nó. Luôn dùng this.name = name!

Lỗi số 3: Thiếu constructor mặc định.
Nếu bạn đã khai báo constructor có tham số nhưng quên thêm constructor rỗng một cách rõ ràng, thì new Person() sẽ không chạy được.

Lỗi số 4: Trùng tên phương thức và lớp.
Trong Java, tên constructor bắt buộc trùng với tên lớp, còn phương thức thì không. Đôi khi người ta nhầm đặt tên phương thức y hệt tên lớp, và trình biên dịch sẽ báo lỗi.

Lỗi số 5: Quên bộ sửa đổi truy cập.
Nếu đặt các trường là public, chúng có thể bị thay đổi ở bất cứ đâu — điều này nguy hiểm cho các chương trình lớn. Tốt hơn là tập làm quen với private và dùng phương thức để truy cập.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION