Saya memiliki kelas dasar Base,. Ini memiliki dua subclass, Sub1dan Sub2. Setiap subkelas memiliki beberapa metode tambahan. Misalnya, Sub1memiliki Sandwich makeASandwich(Ingredients... ingredients), dan Sub2memilikiboolean contactAliens(Frequency onFrequency) .
Karena metode ini mengambil parameter yang berbeda dan melakukan hal yang sama sekali berbeda, mereka sepenuhnya tidak kompatibel, dan saya tidak bisa menggunakan polimorfisme untuk menyelesaikan masalah ini.
Basemenyediakan sebagian besar fungsionalitas, dan saya memiliki banyak koleksi Baseobjek. Namun, semua Basebenda adalah a Sub1atau a Sub2, dan kadang-kadang saya perlu tahu yang mana.
Sepertinya ide yang buruk untuk melakukan hal berikut:
for (Base base : bases) {
if (base instanceof Sub1) {
((Sub1) base).makeASandwich(getRandomIngredients());
// ... etc.
} else { // must be Sub2
((Sub2) base).contactAliens(getFrequency());
// ... etc.
}
}
Jadi saya datang dengan strategi untuk menghindari ini tanpa casting. Basesekarang memiliki metode ini:
boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();
Dan tentu saja, Sub1menerapkan metode ini sebagai
boolean isSub1() { return true; }
Sub1 asSub1(); { return this; }
Sub2 asSub2(); { throw new IllegalStateException(); }
Dan Sub2 mengimplementasikannya dengan cara yang berlawanan.
Sayangnya, sekarang Sub1dan Sub2memiliki metode ini di API mereka sendiri. Jadi saya bisa melakukan ini, misalnya, pada Sub1.
/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1(); { return this; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2(); { throw new IllegalStateException(); }
Dengan cara ini, jika objek diketahui hanya a Base , metode ini tidak ditinggalkan, dan dapat digunakan untuk "melemparkan" dirinya ke jenis yang berbeda sehingga saya dapat memanggil metode subclass di atasnya. Ini tampaknya elegan bagi saya, tetapi di sisi lain, saya agak menyalahgunakan anotasi usang sebagai cara untuk "menghapus" metode dari kelas.
Karena sebuah Sub1instance benar - benar sebuah Base, masuk akal untuk menggunakan warisan daripada enkapsulasi. Apakah yang saya lakukan baik? Apakah ada cara yang lebih baik untuk menyelesaikan masalah ini?
instanceof, dengan cara yang membutuhkan banyak pengetikan, rentan kesalahan, dan membuatnya sulit untuk menambahkan lebih banyak subkelas.
Sub1dan Sub2tidak dapat digunakan secara bergantian, mengapa Anda memperlakukannya seperti itu? Mengapa tidak melacak 'pembuat sandwich' dan 'alien-contacters' Anda secara terpisah?