Mục lục bài họcĐang ở d03-b2
Accessors, Mutators, and the static Keyword
The only doors into a private object
An accessor (getter) returns a copy of some state and changes nothing: public int getCopies() { return copies; }. A mutator (setter) changes state and normally returns void. The reason a mutator beats a public field is that a mutator can refuse: it validates before it writes, so the object can never enter an impossible state.
A local variable declared inside a method exists only until the method returns, and it is not given a default value — using it before assignment is a compile-time error. An instance variable, by contrast, is initialised to the zero value of its type and lives as long as the object does.
static: one copy for the whole class
A static variable belongs to the class, not to any object: every object shares the same single copy, so a counter incremented in a constructor records how many objects have ever been made. A static method is called on the class — Widget.getMade() — and therefore has no this. That single fact explains the whole rule: a static method cannot read an instance variable or call an instance method directly, because there is no particular object to read from.
The reverse direction is always legal: an instance method may freely use static variables and static methods, since the one shared copy exists no matter which object is asking.
Cửa duy nhất đi vào một đối tượng riêng tư
Phương thức truy xuất (accessor, getter) trả về giá trị của một trường và không đổi gì: public int getCopies() { return copies; }. Phương thức thay đổi (mutator, setter) ghi vào trường và thường trả về void. Lý do mutator hơn hẳn một trường public là mutator có quyền từ chối: nó kiểm tra trước khi ghi, nên đối tượng không bao giờ rơi vào trạng thái vô nghĩa.
Biến cục bộ khai trong thân phương thức chỉ sống tới lúc phương thức kết thúc, và không được gán giá trị mặc định — dùng khi chưa gán là lỗi biên dịch. Ngược lại, biến thực thể được khởi tạo về giá trị không của kiểu và sống cùng đối tượng.
static: một bản dùng chung cho cả lớp
Biến static thuộc về lớp chứ không thuộc đối tượng nào: mọi đối tượng dùng chung đúng một bản, nên một biến đếm tăng trong hàm khởi tạo sẽ ghi lại tổng số đối tượng đã từng được tạo. Phương thức static gọi qua tên lớp — Widget.getMade() — và vì thế không có this. Chỉ một sự thật đó giải thích trọn luật: phương thức static không đọc được biến thực thể và không gọi thẳng được phương thức thực thể, vì không có đối tượng cụ thể nào để đọc.
Chiều ngược lại thì luôn hợp lệ: phương thức thực thể dùng thoải mái biến static và phương thức static, vì bản dùng chung đó tồn tại bất kể đối tượng nào đang hỏi.
Bổ sung cho lớp Book: một biến static đếm số đối tượng đã tạo, một accessor static đọc nó, và một mutator setCopies chỉ chấp nhận số không âm. Cho biết sau ba lần new và một lần setCopies(-5) thì trạng thái ra sao.
public class Book {
private String title;
private int copies;
private static int made = 0;
public Book(String title, int copies) {
this.title = title;
this.copies = copies;
made++;
}
public static int getMade() {
return made;
}
public void setCopies(int n) {
if (n >= 0) {
copies = n;
}
}
public int getCopies() {
return copies;
}
}Sau ba lần new Book(...), biến made bằng 3 — không phải mỗi đối tượng một số 1, vì chỉ có một bản dùng chung được ba hàm khởi tạo lần lượt tăng.
Lời gọi b.setCopies(-5) không ném ngoại lệ và cũng không ghi gì: điều kiện n >= 0 sai nên thân if bị bỏ qua, copies giữ nguyên giá trị cũ. Đó chính là quyền từ chối mà một trường public không bao giờ có.
Chú ý getMade() là static nên trong thân nó không được đụng tới title hay copies; nó chỉ đọc được made.
static, rồi ngạc nhiên vì đối tượng nào cũng báo đếm bằng 1. Bẫy số hai, ngược lại: để một dữ liệu riêng của từng đối tượng thành static, khiến đối tượng tạo sau ghi đè giá trị của đối tượng tạo trước. Cách chặn: trước khi gõ static, hỏi đúng một câu — nếu tôi tạo đối tượng thứ hai, giá trị này có phải nhân đôi không? Có thì bỏ static, không thì giữ.static thuộc lớp và chỉ có một bản; phương thức static không có this nên không chạm được biến thực thể, còn phương thức thực thể thì chạm được biến static bất cứ lúc nào.Đọc xong rồi — làm thử ngay
Bài tập của chương Unit 3 — Class Creation gồm 14 câu trắc nghiệm và 8 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.