Soyut bir sınıftan miras alan bir sınıf oluşturduğumuzda ve miras alınan soyut sınıfı uyguladığımızda neden override anahtar sözcüğünü kullanmak zorundayız?
"Neden?" bunun gibi sorulara cevap vermek zor olabilir, çünkü belirsizdirler. Sorunuzun " overrideanahtar kelimenin gerekli olduğu konum için tartışmak üzere dil tasarımı sırasında hangi argümanlar yapılabileceğini" varsayacağım. ?"
Geri adım atarak başlayalım. Java gibi bazı dillerde yöntemler varsayılan olarak sanaldır ve otomatik olarak geçersiz kılınır. C # tasarımcıları bunun farkındaydı ve Java'daki küçük bir kusur olarak kabul etti. C #, bazılarının söylediği gibi "aptal bölümleri çıkarılmış Java" değildir , ancak C # tasarımcıları C, C ++ ve Java'nın sorunlu tasarım noktalarından öğrenmek ve C #'da çoğaltmak istemiyorlardı.
C # tasarımcıları, geçersiz kılmanın olası bir hata kaynağı olduğunu düşündüler; sonuçta , mevcut, test edilmiş kodun davranışını değiştirmenin bir yoludur ve bu tehlikelidir. Geçersiz kılma, rasgele veya kazayla yapılması gereken bir şey değildir; bu konuda çok düşünen biri tarafından tasarlanmalıdır . Bu yüzden yöntemler varsayılan olarak sanal değildir ve neden bir yöntemi geçersiz kıldığınızı söylemeniz gerekir.
Temel akıl yürütme budur. Şimdi daha gelişmiş bir akıl yürütmeye başlayabiliriz.
StriplingWarrior'un cevabı, daha gelişmiş bir argüman yaratmada iyi bir ilk kesinti veriyor. Türetilmiş sınıfın yazarı temel sınıf hakkında bilgi sahibi olmayabilir, yeni bir yöntem yapmaya niyetli olabilir ve kullanıcının yanlışlıkla geçersiz kılmasına izin vermemeliyiz .
Bu nokta mantıklı olsa da, aşağıdakiler gibi bir dizi karşı-değişken vardır:
- Türetilmiş bir sınıfın yazarı , temel sınıfla ilgili her şeyi bilmekle yükümlüdür ! Bu kodu yeniden kullanıyorlar ve yeniden kullanmadan önce bu kodu iyice anlamak için gereken özeni göstermelidirler.
- Özel senaryoda sanal yöntem soyuttur; o bir hata olurdu değil geçersiz ve nedenle yazar kazara bir uygulama yaratmak olacağını olası değildir.
O zaman bu noktada daha da ileri düzeyde bir tartışma yapalım. Hangi koşullarda türetilmiş bir sınıfın yazarı temel sınıfın ne yaptığını bilmediği için mazur görülebilir? Bu senaryoyu düşünün:
- Temel sınıf yazarı soyut bir temel sınıf B yapar.
- Türetilmiş sınıf yazarı, farklı bir ekipte, yöntem M ile türetilmiş bir D sınıfı yapar.
- Temel sınıf yazarı, temel sınıf B'yi genişleten takımların her zaman bir yöntem M sağlaması gerektiğini fark eder, bu nedenle temel sınıf yazarı soyut yöntem M ekler.
- D sınıfı yeniden derlendiğinde ne olur?
Olmak istediğimiz şey, D'nin yazarı, ilgili bir şeyin değiştiği konusunda bilgilendirildi . Değişen ilgili şey, M'nin artık bir gereksinim olduğu ve bunların uygulanmasının aşırı yüklenmesi gerektiğidir. Temel sınıftan çağrılabileceğini bildiğimizde DM'nin davranışını değiştirmesi gerekebilir. Yapılacak doğru şey sessizce "oh, DM vardır ve BM'yi genişletir" demek değildir . Derleyicinin yapacağı doğru şey başarısızdır ve "hey, D'nin yazarı, artık geçerli olmayan bu varsayımına göz atın ve gerekirse kodunuzu düzeltin" deyin.
Örnekte, varsayalım overrideoldu isteğe üzerinde SayHellobir soyut yöntemi geçersiz çünkü. İki olasılık vardır: (1) kodun yazarı soyut bir yöntemi geçersiz kılmak niyetindedir veya (2) bir başkası temel sınıfı değiştirdiğinden ve kod şimdi ince bir şekilde yanlış olduğundan , geçersiz kılma yöntemi yanlışlıkla geçersiz kılınır . İsteğe bağlı ise bu olasılıkları birbirinden overrideayıramayız .
Ama eğer overrideedilir gerekli o zaman ayrı üç senaryo söyleyebilir. Olası bir hata kodu varsa o zaman overridealmaktadır eksik . Kasıtlı geçersiz ise o zaman overrideolduğu mevcut . Ve bilerek eğer değil o zaman ağır basan newbir mevcut . C # 'ın tasarımı bu ince ayrımları yapmamızı sağlar.
Unutmayın raporlama geliştiricinin zihin okuma gerektiren derleyici hatası ; derleyici , yazarın aklındaki doğru kodu yanlış koddan çıkarmalı ve doğru yönde gösteren bir hata vermelidir. Geliştiricinin ne düşündüğüne dair kodda ne kadar fazla ipucu bırakabileceğimize dair, derleyicinin hataları raporlamada yapabileceği daha iyi bir iş ve dolayısıyla hatalarınızı daha hızlı bulabilir ve düzeltebilirsiniz.
Ancak daha genel olarak, C #, kodun değiştiği bir dünya için tasarlanmıştır . "Tek" gibi görünen birçok C # özelliği aslında oradadır, çünkü temel sınıf değiştiği için geçerli olan bir varsayım geçersiz olduğunda geliştiriciyi bilgilendirirler . Bu hata sınıfına "gevrek temel sınıf başarısızlıkları" denir ve C #, bu başarısızlık sınıfı için bir dizi ilginç azaltıcı etkiye sahiptir.