Ketika kita membuat kelas yang mewarisi dari kelas abstrak dan ketika kita menerapkan kelas abstrak yang diwarisi mengapa kita harus menggunakan kata kunci override?
"Mengapa?" pertanyaan seperti ini bisa sulit dijawab karena tidak jelas. Saya akan berasumsi bahwa pertanyaan Anda adalah "argumen apa yang dapat dibuat selama desain bahasa untuk menyatakan posisi yang diperlukanoverride kata kunci ?"
Mari kita mulai dengan mengambil langkah mundur. Dalam beberapa bahasa, katakanlah, Java, metode adalah virtual secara default dan diganti secara otomatis. Para perancang C # menyadari hal ini dan menganggapnya sebagai cacat kecil di Jawa. C # bukan "Java dengan bagian-bagian bodoh dihilangkan" seperti yang dikatakan beberapa orang, tetapi para perancang C # ingin belajar dari titik-titik desain C, C ++ dan Java yang bermasalah, dan tidak mereplikasi mereka dalam C #.
Desainer C # dianggap sebagai sumber bug utama; Lagi pula, ini adalah cara untuk mengubah perilaku kode yang sudah ada dan diuji , dan itu berbahaya. Mengesampingkan bukanlah sesuatu yang harus dilakukan dengan santai atau kebetulan; itu harus dirancang oleh seseorang yang berpikir keras tentangnya . Itu sebabnya metode tidak virtual secara default, dan mengapa Anda diminta untuk mengatakan bahwa Anda mengganti metode.
Itulah alasan dasarnya. Kita sekarang bisa masuk ke beberapa alasan yang lebih maju.
Jawaban StriplingWarrior memberikan potongan pertama yang baik untuk membuat argumen yang lebih maju. Penulis kelas turunan mungkin tidak diberi tahu tentang kelas dasar, mungkin berniat untuk membuat metode baru, dan kami tidak boleh mengizinkan pengguna untuk menimpa secara tidak sengaja .
Meskipun poin ini masuk akal, ada sejumlah tandingan, seperti:
- Penulis kelas turunan memiliki tanggung jawab untuk mengetahui segala sesuatu tentang kelas dasar! Mereka menggunakan kembali kode itu, dan mereka harus melakukan uji tuntas untuk memahami kode itu secara menyeluruh sebelum menggunakannya kembali.
- Dalam skenario khusus Anda metode virtual adalah abstrak; itu akan menjadi kesalahan untuk tidak menimpanya, dan karena itu tidak mungkin bahwa penulis akan membuat implementasi secara tidak sengaja.
Mari kita buat argumen yang lebih maju tentang hal ini. Dalam keadaan apa penulis kelas turunan dapat dimaafkan karena tidak mengetahui apa yang dilakukan kelas dasar? Nah, pertimbangkan skenario ini:
- Penulis kelas dasar membuat kelas dasar abstrak B.
- Penulis kelas turunan, di tim yang berbeda, membuat kelas D turunan dengan metode M.
- Penulis kelas dasar menyadari bahwa tim yang memperluas kelas dasar B akan selalu perlu menyediakan metode M, sehingga penulis kelas dasar menambahkan metode abstrak M.
- Ketika kelas D dikompilasi ulang, apa yang terjadi?
Yang kami inginkan adalah penulis D diberi tahu bahwa sesuatu yang relevan telah berubah . Hal yang relevan yang telah berubah adalah bahwa M sekarang merupakan persyaratan dan bahwa implementasinya harus kelebihan beban. DM mungkin perlu mengubah perilakunya setelah kita tahu bahwa itu bisa dipanggil dari kelas dasar. Hal yang benar untuk dilakukan adalah tidak diam-diam mengatakan "oh, DM ada dan memperluas BM". Hal yang benar untuk dilakukan oleh kompiler adalah gagal , dan katakan "hai, penulis D, lihat asumsi Anda yang tidak lagi valid dan perbaiki kode Anda jika perlu".
Dalam contoh Anda, anggap overridesaja opsional pada SayHellokarena itu menimpa metode abstrak. Ada dua kemungkinan: (1) pembuat kode bermaksud untuk menimpa metode abstrak, atau (2) metode utama diganti secara tidak sengaja karena orang lain mengubah kelas dasar, dan kode tersebut sekarang salah dalam beberapa cara yang halus. Kami tidak dapat membedakan kemungkinan ini jika overrideopsional .
Tetapi jika overrideyang diperlukan maka kita dapat membedakan tiga skenario. Jika ada kesalahan mungkin dalam kode maka overrideyang hilang . Jika sengaja utama kemudian overrideadalah hadir . Dan jika sengaja tidak mengesampingkan kemudian newadalah hadir . Desain C # memungkinkan kita untuk membuat perbedaan yang halus ini.
Ingat, pelaporan kesalahan kompiler memerlukan pembacaan pikiran pengembang ; kompiler harus menyimpulkan dari kode yang salah apa kode yang benar yang mungkin ada dalam pikiran penulis , dan memberikan kesalahan yang mengarahkan mereka ke arah yang benar. Semakin banyak petunjuk yang dapat membuat pengembang meninggalkan kode tentang apa yang mereka pikirkan, semakin baik pekerjaan yang dapat dilakukan oleh kompiler dalam melaporkan kesalahan dan karenanya semakin cepat Anda dapat menemukan dan memperbaiki bug Anda.
Tetapi lebih umum, C # dirancang untuk dunia di mana kode berubah . Banyak sekali fitur C # yang tampak "aneh" sebenarnya ada di sana karena mereka memberi tahu pengembang ketika asumsi yang dulu valid telah menjadi tidak valid karena kelas dasar berubah. Kelas bug ini disebut "kegagalan kelas dasar getas", dan C # memiliki sejumlah mitigasi yang menarik untuk kelas kegagalan ini.