Tidak ada perbedaan antara objek; Anda memiliki HashMap<String, Object>dalam kedua kasus. Ada perbedaan dalam antarmuka yang Anda miliki ke objek. Dalam kasus pertama, antarmuka adalah HashMap<String, Object>, sedangkan yang kedua adalah Map<String, Object>. Tetapi objek yang mendasarinya adalah sama.
Keuntungan menggunakan Map<String, Object>adalah Anda dapat mengubah objek yang mendasarinya menjadi jenis peta yang berbeda tanpa memutus kontrak Anda dengan kode apa pun yang menggunakannya. Jika Anda menyatakannya sebagai HashMap<String, Object>, Anda harus mengubah kontrak Anda jika Anda ingin mengubah implementasi yang mendasarinya.
Contoh: Katakanlah saya menulis kelas ini:
class Foo {
private HashMap<String, Object> things;
private HashMap<String, Object> moreThings;
protected HashMap<String, Object> getThings() {
return this.things;
}
protected HashMap<String, Object> getMoreThings() {
return this.moreThings;
}
public Foo() {
this.things = new HashMap<String, Object>();
this.moreThings = new HashMap<String, Object>();
}
// ...more...
}
Kelas memiliki beberapa peta internal objek string-> yang dibagikan (melalui metode accessor) dengan subclass. Katakanlah saya menulisnya dengan HashMaps karena saya pikir itu adalah struktur yang tepat untuk digunakan ketika menulis kelas.
Kemudian, Mary menulis kode subkelasnya. Dia memiliki sesuatu yang perlu dia lakukan dengan keduanya thingsdan moreThings, jadi secara alami dia menempatkan itu dalam metode umum, dan dia menggunakan tipe yang sama yang saya gunakan pada getThings/ getMoreThingsketika mendefinisikan metodenya:
class SpecialFoo extends Foo {
private void doSomething(HashMap<String, Object> t) {
// ...
}
public void whatever() {
this.doSomething(this.getThings());
this.doSomething(this.getMoreThings());
}
// ...more...
}
Kemudian, saya memutuskan bahwa sebenarnya, lebih baik jika saya menggunakan TreeMapdaripada HashMapdi Foo. Saya memperbarui Foo, berubah HashMapmenjadi TreeMap. Sekarang, SpecialFootidak mengkompilasi lagi, karena saya telah melanggar kontrak: Foodulu mengatakan itu diberikan HashMap, tetapi sekarang menyediakan itu TreeMapssebagai gantinya. Jadi kita harus memperbaikinya SpecialFoosekarang (dan hal semacam ini dapat mengacak basis kode).
Kecuali saya memiliki alasan yang sangat bagus untuk berbagi bahwa implementasi saya menggunakan HashMap(dan itu memang terjadi), apa yang seharusnya saya lakukan adalah menyatakan getThingsdan getMoreThingshanya kembali Map<String, Object>tanpa menjadi lebih spesifik dari itu. Bahkan, kecuali alasan yang baik untuk melakukan sesuatu yang lain, bahkan di dalam Foosaya mungkin harus menyatakan thingsdan moreThingssebagai Map, bukan HashMap/ TreeMap:
class Foo {
private Map<String, Object> things; // <== Changed
private Map<String, Object> moreThings; // <== Changed
protected Map<String, Object> getThings() { // <== Changed
return this.things;
}
protected Map<String, Object> getMoreThings() { // <== Changed
return this.moreThings;
}
public Foo() {
this.things = new HashMap<String, Object>();
this.moreThings = new HashMap<String, Object>();
}
// ...more...
}
Perhatikan bagaimana saya sekarang menggunakan di Map<String, Object>mana saja saya bisa, hanya spesifik ketika saya membuat objek yang sebenarnya.
Jika saya melakukan itu, maka Mary akan melakukan ini:
class SpecialFoo extends Foo {
private void doSomething(Map<String, Object> t) { // <== Changed
// ...
}
public void whatever() {
this.doSomething(this.getThings());
this.doSomething(this.getMoreThings());
}
}
... dan mengubah Footidak akan membuat SpecialFookompilasi berhenti.
Antarmuka (dan kelas dasar) memungkinkan kami mengungkapkan sebanyak yang diperlukan , menjaga fleksibilitas kami di bawah penutup untuk membuat perubahan yang sesuai. Secara umum, kami ingin agar referensi kami sedasar mungkin. Jika kita tidak perlu tahu itu adalah HashMap, sebut saja a Map.
Ini bukan aturan buta, tetapi secara umum, pengkodean ke antarmuka paling umum akan menjadi kurang rapuh daripada pengkodean untuk sesuatu yang lebih spesifik. Jika saya ingat itu, saya tidak akan membuat Fooyang membuat Mary gagal SpecialFoo. Jika Mary ingat itu, maka meskipun aku mengacau Foo, dia akan mendeklarasikan metode pribadinya Mapsebagai ganti HashMapdan dan Fookontrakku yang berubah tidak akan memengaruhi kode etiknya.
Terkadang Anda tidak bisa melakukan itu, terkadang Anda harus spesifik. Tetapi kecuali Anda memiliki alasan untuk itu, berbuat salah menuju antarmuka yang paling tidak spesifik.