2013-05-12 27 views
16

Tôi đã xem qua một số mã lớp mà thực hiện Clonable, tài liệu khẳng định:điểm trong việc cho phép lớp học của tôi thực hiện Cloneable là gì?

Một lớp cài đặt giao diện Cloneable để chỉ cho phương pháp Object.clone() rằng đó là pháp lý cho phương pháp đó để thực hiện một field- sao chép trường cho các cá thể của lớp đó. Gọi phương thức sao chép của đối tượng trên một cá thể không thực hiện các kết quả giao diện Cloneable trong ngoại lệ CloneNotSupportedException bị ném. Theo quy ước, các lớp thực hiện giao diện này sẽ ghi đè Object.clone (được bảo vệ) bằng phương thức công khai. Xem Object.clone() để biết chi tiết về cách ghi đè phương thức này. Lưu ý rằng giao diện này không chứa phương thức sao chép. Do đó, không thể sao chép một đối tượng chỉ bằng thực tế là nó thực hiện giao diện này. Ngay cả khi phương thức sao chép được gọi một cách phản xạ, thì không có gì đảm bảo rằng nó sẽ thành công.

Tôi không thể hiểu được điểm khi triển khai lớp này, như đã nói trong tài liệu phương pháp .clone không được triển khai trong giao diện và tôi phải triển khai. Vậy tại sao lại sử dụng lớp này? Tại sao tôi không chỉ viết một phương thức copyClass trong lớp của mình để sao chép đối tượng mà không cần thực hiện lớp này?

Xin cảm ơn trước.

+1

Bạn có lớp học của bạn thực hiện Cloneable để bạn có thể sử dụng các cơ chế nhân bản tích hợp, vì vậy các lớp khác có thể sao chép của bạn mà không cần phải biết đó là phương thức sao chép duy nhất. Vâng, đó là một cách lạ để quản lý nó, nhưng một phần nó phải làm với khả năng tương thích ngược. –

Trả lời

22

Để thực hiện các phương pháp nhân bản, bạn chỉ cần làm:

public Object clone() throws CloneNotSupportedException { 
    return super.clone(); 
} 

Bạn dĩ nhiên có thể tùy chỉnh các phương pháp để tạo một bản sao sâu hơn nếu cần thiết.

Gọi super.clone() gần như là bắt buộc vì, trừ khi lớp là cuối cùng và do đó không thể bị ghi đè, phương thức clone() phải trả về một thể hiện của cùng một lớp với đối tượng mà nó được gọi. Vì vậy, chỉ cần tạo một thể hiện mới và sao chép trạng thái sẽ làm việc cho lớp này, nhưng không phải cho tất cả các lớp con. Hơn nữa, bạn không phải lúc nào cũng có quyền truy cập vào tất cả trạng thái chứa trong các siêu lớp.

Tóm lại, bạn thực hiện phương pháp sao chép được bảo vệ của đối tượng công khai. Và điều đầu tiên mà các phương pháp Object.clone() làm là (điều này không phải là mã thật, nhưng đây là những gì phương pháp nào):

if (!(this instanceof Cloneable)) { 
    throw new CloneNotSupportedException(); 
} 

Vì vậy, Cloneable chỉ là một giao diện đánh dấu để cho các phương pháp Object.clone() biết rằng nó không được ném một ngoại lệ khi được gọi.

Đây là một trong những phần được thiết kế kém nhất của Java. Thông thường, bạn nên sử dụng một bản sao contructor thay vì sử dụng clone().

+0

Cũng như tôi có thể hiểu từ câu trả lời của bạn, hôm nay điều này không được khuyến khích sử dụng giao diện này, và nó chỉ sử dụng là: nếu tôi muốn sử dụng phương pháp nhân bản của lớp Object thì tôi nên thực hiện nó. Trong trường hợp của tôi (lớp mà tôi thấy việc thực hiện này) một bản sao sâu hơn của lớp đã được thực hiện, Vì vậy, trong trường hợp này là bất kỳ lý do gì để thực hiện giao diện này? –

+0

Nếu bạn muốn ghi đè và sử dụng phương thức 'Object.clone()', bạn cần triển khai giao diện này. Nếu bạn muốn thực hiện một bản sao theo cách khác, sau đó chỉ cần làm bất cứ điều gì bạn muốn. –

+0

Có ya, để ghi đè Object.clone() buộc tôi sử dụng giao diện này. Cảm ơn câu trả lời thông tin của bạn. –

1

Nó cho phép bạn viết mã chung hơn. Nếu bạn có nhiều lớp thực hiện giao diện Cloneable và muốn chuyển các đối tượng của chúng làm đối số cho phương thức, bạn không phải tạo nhiều phương thức khác với một loại biến, bạn chỉ có thể sử dụng Cloneable t. Nó giống với các giao diện khác. Và, tương tự với mọi giao diện khác, nó khá đa dạng. Việc triển khai các giao diện đó làm cho mã của bạn dễ đọc hơn.

Các vấn đề liên quan