Truy cập đối tượng qua biến tham chiếu

Lập trình Hướng Đối tượng

Dữ liệu và phương thức của đối tượng có thể được truy cập thông qua toán tử dấu chấm (.)qua biến tham chiếu của đối tượng.

Các đối tượng được tạo mới được cấp phát trong bộ nhớ. Chúng có thể được truy cập thông qua các biến tham chiếu.

1. Biến tham chiếu và kiểu dữ liệu tham chiếu (Reference Variables and Reference Types)

Các đối tượng được truy cập qua biến tham chiếu của đối tượng, biến tham chiếu của đối tượng chứa tham chiếu tới các đối tượng. Các biến như vậy được khai báo sử dụng cú pháp sau:

 ClassName objectRefVar;

Một lớp về bản chất là một kiểu dữ liệu do lập trình viên định nghĩa. Một lớp là một kiểu dữ liệu tham chiếu, có nghĩa là một biến của lớp có thể tham chiếu tới một thể hiện của lớp. Câu lệnh sau khai báo biến myCircle thuộc kiểu Circle:

Circle myCircle;

Biến myCircle có thể tham chiếu tới đối tượng Circle. Câu lệnh tiếp theo tạo một đối tượng và gán tham chiếu của nó tới myCircle:

myCircle = new Circle();

Bạn có thể viết một câu lệnh đơn giản kết hợp khai báo một biến tham chiếu đối tượng, tạo ra một đối tượng và gán đối tượng tham chiếu đến biến với cú pháp sau:

ClassName objectRefVar = new ClassName();

Đây là một ví dụ:

Circle myCircle = new Circle();

Biến myCircle giữ một tham chiếu tới đối tượng Circle

Chú ý

Một biến tham chiếu đối tượng xuất hiện để giữ một tham chiếu tới đối tượng đó. Một biến tham chiếu đối tượng và một đối tượng là khác nhau, nhưng phần lớn sự khác biệt này bị bỏ qua. Vì vậy, để đơn giản, tốt nhất hãy nói rằng myCircle là một đối đối tượng Circle thay vì mô tả lòng vòng rằng myCircle là một biến mà chứa tham chiếu tới đối tượng Circle.

Chú ý

Mảng được xem như là các đối tượng trong Java. Mảng được tạo bằng cách sử dụng toán tử new.

2. Truy cập phương thức và dữ liệu của đối tượng

Trong thuật ngữ OOP, thành viên của đối tượng được biết đến là trường dữ liệu và phương thức của nó. Sau khi đối tượng được tạo, trường dữ liệu và phương thức có thể được truy cập bằng cáh sử dụng toán tử chấm (.), toán tử (.) còn được gọi là toán tử truy cập thành viên đối tượng.

  • objectRefVar.dataField tham chiếu tới trường dữ liệu trong đối tượng 
  • objectRefVar.method(arguments) gọi phương thức trên đối tượng. 

Ví dụ, myCircle.radius tham chiếu tới bán kính trong myCircle, và myCircle .getArea() gọi phương thức getArea trên myCircle.

Trường dữ liệu radius được gọi là instance variable, bởi vì nó phụ thuộc vào một instance cụ thể. Do đó, phương thức getArea được cũng được gọi là instance method, bởi vì bạn chỉ có thể gọi nó trên một instance. Đối tượng mà một instance method được gọi thì gọi là calling object.

Chú ý

Nhớ lại rằng bạn sử dụng Math.methodName(arguments) (ví dụ, Math.pow(3, 2.5)) để gọi một phương thức trong lớp Math. Bạn có thể gọi getArea() bằng cách sử dụng Circle.getArea() không? Câu trả lời là không. Tất cả các phương thức trong lớp Math là các phương thức static, được định nghĩa bằng cách sử dụng từ khoá static. Tuy nhiên, getArea() là một instance method, và không phải là phương thức static. Nó phải được gọi từ một đối tượng bằng cách objectRefVar.methodName(arguments) (ví dụ, myCircle.getArea()).

Chú ý

Thường bạn tạo một đối tượng và gán nó cho một biến, sau đó bạn có thể sử dụng biến để tham chiếu đối tượng. Đôi khi một đối tượng không cần phải được tham chiếu sau. Trong trường hợp này, bạn có thể tạo ra một đối tượng mà không cần gán nó cho biến bằng cách sử dụng cú pháp sau:

 new Circle();

hoặc

 System.out.println("Area is " + new Circle(5).getArea());

Câu lênh (1) tạo một đối tượng Circle. Câu lênh (2) tạo một đối tượng Circle và gọi phương thức getArea để trả về diện tích hình tròn. Một đối tượng được tạo theo cách này được gọi là đối tượng nạc danh (anonymous object).

3. Trường dữ liệu tham chiếu (Reference Data Fields) và giá trị null

Các trường dữ liệu có thể là các kiếu tham chiếu. Ví dụ, lớp Student sau chứa trường name thuộc kiểu String. String là một lớp trong Java đã được định nghĩa trước.

class Student {
   String name; // name có giá trị mặc định là null
   int age; // age có giá trị mặc định là 0
   boolean isScienceMajor; // isScienceMajor có giá trị mặc định là false
   char gender; // gender có giá trị mặc định là '\u0000'
}

Nếu một trường dữ liệu của một kiểu tham chiếu không tham chiếu tới bất kỳ đối tượng nào, trường dữ liệu giữ một giá trị Java đặc biệt là nullnull là một literal giống như true và false. Trong khi true và false là các literal thuộc kiểu Boolean, thì null là một literal thuộc kiểu tham chiếu.

Giá trị mặc định của trường dữ liệu là null cho mọi kiểu tham chiếu, 0 cho kiểu dạng số, false cho kiểu boolean, và \u0000 cho kiểu ký tự. Tuy nhiên, Java không gán giá trị mặc định cho biến local trong phương thức. Đoạn mã sau hiển thị giá trị mặc định của các trường nameageisScienceMajor, và gender cho đối tượng Student:

class Test {
   public static void main(String[] args) {
      Student student = new Student();
      System.out.println("name? " + student.name);
      System.out.println("age? " + student.age);
      System.out.println("isScienceMajor? " + student.isScienceMajor);
      System.out.println("gender? " + student.gender);
   }
}

Đoạn mã sau có lỗi biên dịch, bởi vì biến local x và y chưa được khởi tạo:

class Test {
   public static void main(String[] args) {
      int x; // x has no default value
      String y; // y has no default value
      System.out.println("x is " + x);
      System.out.println("y is " + y);
   }
}

Chú ý

NullPointerException là lỗi rantime phổ biến. Nó xảy ra khi bạn gọi một phương thức trên một biến tham chiếu với một giá trị null. Hãy đảm bảo bạn gán một tham chiếu đối tượng cho biến trước khi gọi phương thức thông qua biến tham chiếu.

4 Sự khác nhau giữa biến của kiểu dữ liệu nguyên thuỷ và kiểu dữ liệu tham chiếu

Mỗi biến đại diện cho một vị trí trong bộ nhớ mà lưu giữ một giá trị. Khi bạn khai báo một biến, bạn sẽ nói với trình biên dịch kiểu dữ liệu của giá trị mà biến có thể giữ. Đối với một biến có kiểu dữ liệu nguyên thuỷ, giá trị là của kiểu dữ liệu nguyên thuỷ. Đối với một biến kiểu tham chiếu, giá trị là một tham chiếu đến vị trí của đối tượng được cấp phát. Ví dụ, như trong hình 1, giá trị của biến số nguyên là một số nguyên 1, và giá trị của đối tượng c của Circle chứa một tham chiếu tới nơi mà nội dung của đối tượng Circle được lưu trữ trong bộ nhớ.

Khi bạn chỉ định một biến cho một biến khác, biến khác được thiết đặt với cùng một giá trị. Đối với biến kiểu nguyên thuỷ, giá trị thực của một biến được gán cho một biến khác. Đối với một biến kiểu tham chiếu, tham chiếu của một biến được gán cho một biến khác. Như trong hình 2, lệnh gán i = j sao chép nội dung của j vào I đối với biến nguyên thuỷ. Như trong hình 3, lệnh gán c1 = c2, sao chép tham chiếu của c2 vào c1 đối với biến tham chiếu. Sau khi thực hiện gán, biến c1 và c2 tham chiếu tới cùng một đối tượng.

Hình 1. Một biến thuộc kiểu nguyên thuỷ giữ giá trị của kiểu nguyên thuỷ, và một biến của kiểu tham chiếu giữ một tham chiếu tới tới vị trí của đối tượng được lưu trữ trong bộ nhớ.

Hình 2. Biến nguyên thuỷ j sao chép nội dung sang biến i.

Hình 3: Biến tham chiếu c2 được sao chép tới biến c1

Chú ý

Như minh họa trong hình 3, sau câu lệnh gán c1 = c2, c1 trỏ tới cùng một đối tượng được tham chiếu bởi c2. Đối tượng được tham chiếu trước đó bởi c1 không còn hữu ích nữa và do đó bây giờ được gọi là rác (garbage). Garbage chiếm không gian bộ nhớ, do đó,  hệ thống Java runtime khi phát hiện ra garbage sẽ tự động lấy lại không gian nó chiếm. Quá trình này được gọi là thu gom rác (garbage collection).

Chú ý

Nếu bạn biết rằng một đối tượng không còn cần thiết, bạn có thể gán một cách rõ ràng null cho một tham chiếu biến cho đối tượng. JVM sẽ tự động thu thập không gian nếu đối tượng không được tham chiếu bởi bất kỳ biến tham chiếu nào.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

Leave a Reply

Your email address will not be published. Required fields are marked *