Kelemahan hierarki kelas tradisional yang terkenal adalah bahwa mereka buruk ketika datang ke pemodelan dunia nyata. Sebagai contoh, berusaha mewakili spesies hewan dengan kelas. Sebenarnya ada beberapa masalah ketika melakukan itu, tetapi satu yang saya tidak pernah lihat solusinya adalah ketika sub-kelas "kehilangan" perilaku atau properti yang didefinisikan dalam kelas-super, seperti seekor penguin yang tidak bisa terbang (ada mungkin contoh yang lebih baik, tapi itu yang pertama muncul di benak saya).
Di satu sisi, Anda tidak ingin mendefinisikan, untuk setiap properti dan perilaku, beberapa bendera yang menentukan jika semuanya ada, dan memeriksanya setiap kali sebelum mengakses perilaku atau properti itu. Anda hanya ingin mengatakan bahwa burung dapat terbang, secara sederhana dan jelas, di kelas Burung. Tetapi kemudian akan lebih baik jika seseorang dapat mendefinisikan "pengecualian" sesudahnya, tanpa harus menggunakan beberapa peretasan yang mengerikan di mana-mana. Ini sering terjadi ketika suatu sistem telah produktif untuk sementara waktu. Anda tiba-tiba menemukan "pengecualian" yang sama sekali tidak sesuai dengan desain aslinya, dan Anda tidak ingin mengubah sebagian besar kode Anda untuk mengakomodasi itu.
Jadi, apakah ada beberapa bahasa atau pola desain yang dapat menangani masalah ini dengan bersih, tanpa memerlukan perubahan besar pada "super-class", dan semua kode yang menggunakannya? Bahkan jika suatu solusi hanya menangani kasus tertentu, beberapa solusi mungkin bersama-sama membentuk strategi yang lengkap.
Setelah berpikir lebih jauh, saya sadar saya lupa tentang Prinsip Pergantian Liskov. Itu sebabnya kamu tidak bisa melakukannya. Dengan asumsi Anda mendefinisikan "ciri / antarmuka" untuk semua "kelompok fitur" utama, Anda dapat dengan bebas menerapkan ciri-ciri di berbagai cabang hierarki, seperti sifat Terbang dapat diimplementasikan oleh Burung, dan beberapa jenis tupai dan ikan.
Jadi pertanyaan saya bisa berjumlah "Bagaimana saya bisa membatalkan penerapan suatu sifat?" Jika super-class Anda adalah Java Serializable, Anda harus menjadi salah satu juga, bahkan jika tidak ada cara bagi Anda untuk membuat serial keadaan Anda, misalnya jika Anda mengandung "Socket".
Salah satu cara untuk melakukannya adalah dengan selalu mendefinisikan semua sifat Anda berpasangan sejak awal: Terbang dan Tidak Menempati (yang akan melempar UnsupportedOperationException, jika tidak dicentang). Tidak-sifat tidak akan mendefinisikan antarmuka baru, dan dapat dengan mudah diperiksa. Kedengarannya seperti solusi "murah", khususnya jika digunakan sejak awal.
" it would be nice if one could define "exceptions" afterward, without having to use some horrible hacks everywhere"
apakah Anda mempertimbangkan metode pabrik yang mengendalikan perilaku hacky?
NotSupportedException
dari Penguin.fly()
.
class Penguin < Bird; undef fly; end;
. Apakah Anda harus menjawab pertanyaan lain?
function save_yourself_from_crashing_airplane(Bird b) { f.fly() }
akan menjadi jauh lebih rumit. (seperti yang dikatakan Peter Török, itu melanggar LSP)