Saya baru-baru ini harus memperbarui kelas dasar abstrak pada beberapa OSS yang saya gunakan sehingga lebih dapat diuji dengan membuatnya virtual (saya tidak dapat menggunakan antarmuka karena menggabungkan dua). Ini membuat saya berpikir apakah saya harus menandai semua metode yang saya butuhkan virtual, atau jika saya harus menandai setiap metode publik / properti virtual. Saya umumnya setuju dengan Roy Osherove bahwa setiap metode harus dibuat virtual, tetapi saya menemukan artikel ini yang membuat saya berpikir apakah ini perlu atau tidak . Saya akan membatasi ini ke kelas abstrak untuk kesederhanaan, namun (apakah semua metode publik konkrit harus virtual masih bisa diperdebatkan, saya yakin).
Saya bisa melihat di mana Anda mungkin ingin mengizinkan sub-kelas untuk menggunakan metode, tetapi tidak ingin itu menimpa implementasi. Namun, selama Anda percaya bahwa Prinsip Pergantian Liskov akan diikuti, lalu mengapa Anda tidak membiarkannya diganti? Dengan menandainya sebagai abstrak, Anda memaksakan sebuah override tertentu, jadi, menurut saya semua metode publik di dalam kelas abstrak memang harus ditandai virtual.
Namun, saya ingin bertanya jika ada sesuatu yang mungkin tidak saya pikirkan. Haruskah semua metode publik dalam kelas abstrak dibuat virtual?
sumber
Jawaban:
Sebagai contoh, karena saya ingin implementasi kerangka suatu algoritma diperbaiki, dan hanya memungkinkan bagian-bagian tertentu untuk didefinisikan kembali oleh subkelas. Ini secara luas dikenal sebagai pola Metode Templat (penekanan di bawah oleh saya):
Memperbarui
Beberapa contoh nyata proyek yang telah saya kerjakan:
Dalam dua kasus pertama, implementasi warisan asli menggunakan Strategi , menghasilkan banyak kode duplikat, yang tentu saja selama bertahun-tahun tumbuh perbedaan halus di sana-sini, mengandung banyak bug yang digandakan atau sedikit berbeda, dan sangat sulit untuk dipelihara. Refactoring ke Metode Templat (dan beberapa perangkat tambahan lainnya, seperti menggunakan anotasi Java) mengurangi ukuran kode sekitar 40-70%.
Ini hanya contoh terbaru yang muncul di benak saya. Saya bisa mengutip lebih banyak kasus dari hampir setiap proyek yang saya kerjakan sejauh ini.
sumber
Sangat masuk akal, dan kadang-kadang diinginkan untuk memiliki metode non-virtual dalam kelas dasar abstrak; hanya karena kelas abstrak tidak selalu berarti setiap bagiannya harus dapat digunakan secara polimorfik.
Misalnya, Anda mungkin ingin menggunakan idiom 'Non virtual polymorphism', di mana suatu fungsi disebut secara polimorfis dari fungsi anggota non-virtual, untuk memastikan bahwa prasyarat atau postkondisi tertentu terpenuhi sebelum fungsi virtual disebut
sumber
Cukup untuk sebuah kelas mengandung SATU metode virtual, agar kelas menjadi abstrak. Anda mungkin ingin memperhatikan metode mana yang Anda inginkan virtual dan yang tidak, sesuai dengan jenis polimorfisme yang Anda rencanakan untuk digunakan.
sumber
Tanyakan pada diri sendiri apa gunanya metode non-virtual di kelas abstrak. Metode seperti itu harus memiliki implementasi agar bermanfaat. Tetapi jika kelas memiliki implementasi, apakah masih bisa disebut kelas abstrak? Bahkan jika bahasa / kompiler memungkinkan, apakah masuk akal? Secara pribadi, saya kira tidak. Anda akan memiliki kelas normal dengan metode abstrak yang diharapkan dapat diterapkan oleh keturunan.
Bahasa utama saya adalah Delphi, bukan C #. Dalam Delphi, jika Anda menandai metode abstrak, Anda juga harus menandainya virtual atau kompiler mengeluh. Belum mengikuti perubahan bahasa terbaru terlalu dekat, tetapi jika kelas abstrak ada di atau akan datang ke Delphi, saya akan berharap kompiler mengeluh tentang metode non-virtual, metode pribadi apa pun dan tentang implementasi metode apa pun untuk kelas yang ditandai abstrak di tingkat kelas.
sumber
abstract
, Anda juga harus menandai seluruh kelasabstract
.Anda tidak membuat metode tertentu virtual karena Anda tidak percaya ini menjadi masalahnya. Lebih lanjut, dengan membuat metode tertentu bukan virtual, Anda memberi sinyal kepada pewaris metode apa yang harus diterapkan.
Secara pribadi, saya akan sering membuat kelebihan metode yang ada untuk kenyamanan bukan virtual sehingga pengguna kelas dapat memiliki default yang konsisten dan pelaksana bahkan tidak dapat membuat kesalahan dengan melanggar perilaku tersirat itu.
sumber