Các biến và phơng thức thể hiện đợc liên kết với các thể hiện của một lớp. Để kích hoạt phơng thức thể hiện f liên kết vơí đối tợng o, chúng ta viết o.f(...); ođợc gọi là ngời nhận (receiver) của f, và f có thể tham chiếu tới các biến thể hiện của o
một cách trực tiếp. Nếu ocó một biến thể hiện chung (public) x, các khách hàng có thể tham chiếu tới nó bằng ký hiệu o.x.
Các biến lớp (class variables) đợc liên kết với một lớp, chứ không phải với các thể hiện của lớp đó. Có một thể hiện của mỗi biến lớp, chứ không phải cho từng đối tợng. Để tạo một biến lớp, chúng ta bổ sung từ khóa static vào đầu phần mô tả biến. Một phơng thức lớp (class method), tơng tự, là phơng thức không liên kết với một đối tợng nào, mà với toàn bộ lớp. Một phơng thức lớp không đợc kích hoạt bằng cách gửi nó nh một thông điệp tới một đối tợng; nó không có ngời nhận nào cả. Phơng thức f của lớp C
đợc kích hoạt bằng ký hiệu C.f(...). Bởi vì một phơng thức lớp thì không có ngời nhận, nó không thể tham chiếu tới các biến thể hiện. Cũng giống nh các biến lớp, các
phơng thức lớp đợc tạo ra bằng từ khoá static. Mối quan hệ giữa các biến thể hiện và các biến lớp đợc minh hoạ trên hình 8.1.
Để hiểu rõ lợi ích của các biến lớp và phơng thức lớp, háy xem xét tình huống lập trình sau: Trong một ứng dụng hay applet sử dụng lớp Time, ngời sử dụng đợc phép chọn cách mà các đối tợng Time đợc in ra, và đôi khi họ muốn dùng thời gian theo kiểu quân sự thay vì theo định dạng thông thờng. Chơng trình ứng dụng có thể cho phép ngời sử dụng nhập một lệnh chuyển đổi giữa hai kiểu định dạng; với applet, có thể dụng một hộp kiểm. Trong mỗi trờng hợp, chơng trình cần phải nhớ đợc định dạng nào đợc dùng cho đến khi đợc chuyển đổi lại.
Một cách làm là duy trì một biến boolean useMilitaryTime. Mỗi khi một đối tợng Time (gọi là now) đợc in ra, nó đợc bao trong một điều lệnh if-then-else:
if (useMilitaryTime)
now.printMilitaryTime;
else
now.printTime;
trong đó lớp Time định nghĩa phơng thức thể hiện printMilitaryTime. Tuy nhiên, bởi vì các đối tợng Time có thể đợc in ra sử dụng nhiều phơng thức, biến
useMilitaryTime sẽ phải đợc truyền cho tất cả chúng nh một tham số bổ sung.
Một giải pháp khác là định nghĩa một phơng thức chuyển đổi cho biến thể hiện
useMilitaryTime. Phơng thức printTime sẽ tham khảo tới biến này để quyết định cách in thời gian:
public class Time
{
private boolean useMilitaryTime = false;
class objects a b y x y x y x
...void toggleTimeFormat() void toggleTimeFormat() { useMilitaryTime = !useMilitaryTime; } ... void printTime() { if (useMilitaryTime)
// in định dạng thời gian quân sự
else
// in định dạng thời gian thờng
}
...
}
Khách hàng sẽ chuyển tới định dạng thời gian quân sự bằng lời gọi
now.toggleTimeFormat, và gửi thông điệp printTime để in ra. Tuy nhiên, cách làm này vẫn có một nhợc điểm quan trọng