Phương thức clone()
Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 43 trên 87.
Phương thức clone() tạo bản sao của một đối tượng. Để dùng phương thức này, lớp của bạn phải triển khai giao diện Cloneable và ghi đè phương thức clone() của lớp Object.
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}Giờ bạn có thể tạo các bản sao độc lập của đối tượng:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy là một đối tượng (object) riêng biệt có cùng các giá trịTheo mặc định, clone() thực hiện bản sao nông, nghĩa là nó sao chép các giá trị nguyên thủy và tham chiếu. Nếu đối tượng của bạn chứa các đối tượng khác làm trường, cả đối tượng ban đầu lẫn bản sao đều tham chiếu đến cùng các đối tượng lồng nhau. Để tạo các bản sao độc lập thực sự có chứa đối tượng lồng nhau, bạn cần triển khai bản sao sâu bằng cách sao chép cả những đối tượng lồng nhau đó trong phương thức clone().
Thử thách
DễHãy xây dựng một hệ thống quản lý tài liệu để minh họa việc sao chép đối tượng (object cloning). Bạn sẽ tạo một lớp Document có thể được sao chép để tạo ra các bản sao độc lập, cho phép người dùng nhân bản tài liệu mà vẫn giữ nguyên bản gốc.
Bạn sẽ chia code thành hai tệp:
Document.java: Tạo một lớp đại diện cho tài liệu và hỗ trợ sao chép. Một tài liệu có ba trường riêng tư:title(String),author(String) vàversion(int). Thêm hàm khởi tạo để khởi tạo tất cả các trường cùng phương thức getter cho từng trường. Đồng thời, thêm phương thứcsetVersion(int version)để cập nhật số phiên bản.Cho lớp Document triển khai giao diện
Cloneablevà ghi đè phương thứcclone()để trả về mộtDocument. Xử lýCloneNotSupportedExceptionbên trong phương thức bằng cách bọc ngoại lệ này trong mộtRuntimeException.Ghi đè
toString()để trả về:Document[title=X, author=Y, version=Z], trong đó X, Y và Z là giá trị thực tế của các trường.Main.java: Tạo một tài liệu và sao chép nó để lớp Document hoạt động. Bạn sẽ nhận ba đầu vào: tiêu đề (String), tác giả (String) và số phiên bản (int).Tạo một tài liệu gốc bằng các giá trị này, sau đó sao chép tài liệu để tạo bản sao. Sau khi sao chép, tăng phiên bản của bản sao thêm 1 bằng
setVersion(). Điều này cho thấy bản sao thực sự độc lập với bản gốc.In ra ba dòng:
Original:theo sau là kết quảtoString()của tài liệu gốcClone:theo sau là kết quảtoString()của tài liệu được sao chépIndependent:theo sau làtruehoặcfalse, cho biết tài liệu gốc và bản sao có phải là hai đối tượng khác nhau hay không (dùng phép so sánh!=)
Bạn sẽ nhận ba đầu vào: tiêu đề tài liệu (String), tên tác giả (String) và số phiên bản (int).
Hãy chú ý rằng sau khi sửa phiên bản của bản sao, tài liệu gốc vẫn không thay đổi. Điều này chứng minh rằng clone() đã tạo ra một bản sao thực sự độc lập!
Tự làm thử
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Đọc các giá trị đầu vào
String title = scanner.nextLine();
String author = scanner.nextLine();
int version = scanner.nextInt();
// TODO: Tạo một Document gốc với các giá trị đầu vào
// TODO: Clone tài liệu gốc để tạo bản sao
// TODO: Tăng version của bản clone thêm 1
// TODO: In "Original: " rồi đến tài liệu gốc
// TODO: In "Clone: " rồi đến tài liệu đã clone
// TODO: In "Independent: " rồi đến true/false (kiểm tra original != clone)
}
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online