Ta lại tiếp tục chủ đề hướng đối tượng với khái niệm tham chiếu, copy đối tượng
Từ các phần trước ta đã biết qua các khái niệm lớp, đối tượng, và các cách làm viêc với chúng
Trong phần này ta sẽ tìm hiểu về hoạt động của đối tượng
Xét lớp sau
Từ các phần trước ta đã biết qua các khái niệm lớp, đối tượng, và các cách làm viêc với chúng
Trong phần này ta sẽ tìm hiểu về hoạt động của đối tượng
Xét lớp sau
package test1;
public class ClassA {
private String field;
/**
* @return the field
*/
public String getField() {
return field;
}
/**
* @param field the field to set
*/
public void setField(String field) {
this.field = field;
}
}
Khi chúng ta khởi tạo một đối tượng thông qua toán tử new
ClassA objA = new ClassA();
Hệ thống sẽ cung cấp một vùng nhớ tương ứng với lớp ClassA, và vùng nhớ này sẽ được trỏ đến bởi tham chiếu objA
Sau đó
objA.setField("field 1");
thì giá trị "field 1" sẽ được lưu vào vùng nhớ đã được cấp thông qua tham chiếu objA
System.out.println("1. a: " + a.getField()); sẽ cho kết quả là 1.a : field 1
Với một khởi tạo khác
ClassA objB = new ClassA();
Hệ thống sẽ tiếp tục cung cấp một vùng nhớ tương ứng với lớp ClassA và vùng này sẽ được trỏ đến bởi tham chiếu objB
Nếu ta tiếp tục thao tác như trên thì không có gì xảy ra, nhưng giả sử ta thực hiện như sau
objB = objA;
hoặc ClassA objB = objA;
thì khi này hệ thống không cung cấp vùng nhớ để tham chiếu objB trỏ vào mà hệ thống sẽ cho tham chiếu objB trỏ vào vùng nhớ mà tham chiếu objA đã trỏ vào. Và khi đó, 2 tham chiếu objA, objB sẽ có chung một vùng nhớ, những thay đổi từ 2 tham chiếu này sẽ được đưa vào vùng nhớ trênm và sẽ 'ảnh hưởng' lẫn nhau
ClassA objA = new ClassA();
objA.setField("field 1");
ClassA objB = objA;
System.out.println("1. a: " + objA.getField()); => 1. a: field 1
System.out.println("1. b: " + objB.getField()); => 1. b: field 1
objA.setField("field 2");
System.out.println("2. a: " + objA.getField()); => 2. a: field 2
System.out.println("2. b: " + objB.getField()); => 2. b: field 2
objB.setField("field 3");
System.out.println("3. a: " + objA.getField()); => 3. a: field 3
System.out.println("3. b: " + objB.getField()); => 3. b: field 3
Như vậy toán tử new sẽ khởi tạo vùng nhớ mới cho đối tượng, và toán tử = chỉ đơn giản là cùng trỏ hai tham chiếu vào cùng một vùng nhớ chứ không mang tính copy hoàn toàn đối tượng
Như vậy, với lớp ClassA ta có thể viết tiếp một phương thức copy 'bản thân' nó thành một đối tượng mới như sau
package test1;
public class ClassA {
private String field;
/**
* @return the field
*/
public String getField() {
return field;
}
/**
* @param field the field to set
*/
public void setField(String field) {
this.field = field;
}
public ClassA clone(){
ClassA obj = new ClassA();
obj.setField(this.field);
return obj;
}
}
Phương thức clone() sẽ copy hoàn toàn một đối tượng hiện tại
ClassA objA = new ClassA();
objA.setField("field 1");
ClassA objB = objA;
ClassA objC = objA.clone();
System.out.println("1. a: " + objA.getField()); => 1. a: field 1
System.out.println("1. b: " + objB.getField()); => 1. b: field 1
System.out.println("1. c: " + objC.getField()); => 1. c: field 1
objA.setField("field 2");
System.out.println("2. a: " + objA.getField()); => 2. a: field 2
System.out.println("2. b: " + objB.getField()); => 2. b: field 2
System.out.println("2. c: " + objC.getField()); => 2. c: field 1
objB.setField("field 3");
System.out.println("3. a: " + objA.getField()); => 3. a: field 3
System.out.println("3. b: " + objB.getField()); => 3. b: field 3
System.out.println("3. c: " + objC.getField()); => 3. c: field 1
No comments:
Post a Comment