Kloning adalah paradigma pemrograman dasar. Fakta bahwa Java mungkin telah menerapkannya dengan buruk dalam banyak hal tidak mengurangi kebutuhan kloning sama sekali. Dan, mudah untuk mengimplementasikan kloning yang akan bekerja sesuai keinginan Anda, dangkal, dalam, campuran, apa pun. Anda bahkan dapat menggunakan nama clone untuk fungsi tersebut dan tidak mengimplementasikan Cloneable jika Anda mau.
Misalkan saya memiliki kelas A, B, dan C, di mana B dan C berasal dari A. Jika saya memiliki daftar objek tipe A seperti ini:
ArrayList<A> list1;
Sekarang, daftar itu bisa berisi objek tipe A, B, atau C. Anda tidak tahu apa tipe objek itu. Jadi, Anda tidak dapat menyalin daftar seperti ini:
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
list2.add(new A(a));
}
Jika objek sebenarnya tipe B atau C, Anda tidak akan mendapatkan salinan yang benar. Dan, bagaimana jika A abstrak? Sekarang, beberapa orang menyarankan ini:
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
if(a instanceof A) {
list2.add(new A(a));
} else if(a instanceof B) {
list2.add(new B(a));
} else if(a instanceof C) {
list2.add(new C(a));
}
}
Ini adalah ide yang sangat, sangat buruk. Bagaimana jika Anda menambahkan tipe turunan baru? Bagaimana jika B atau C ada dalam paket lain dan Anda tidak memiliki akses ke mereka di kelas ini?
Apa yang ingin Anda lakukan adalah:
ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
list2.add(a.clone());
}
Banyak orang telah menunjukkan mengapa implementasi dasar Java dari klon bermasalah. Tapi, mudah diatasi dengan cara ini:
Di kelas A:
public A clone() {
return new A(this);
}
Di kelas B:
@Override
public B clone() {
return new B(this);
}
Di kelas C:
@Override
public C clone() {
return new C(this):
}
Saya tidak menerapkan Cloneable, hanya menggunakan nama fungsi yang sama. Jika Anda tidak menyukainya, beri nama lain.