Soru C # 'soyut geçersiz kılma' kullanımı nedir?


Sadece meraktan yola çıkarak, temel sınıfta soyut bir yöntemi geçersiz kılmaya çalıştım ve uygulama özeti yöntemini. Aşağıda olduğu gibi:

public abstract class FirstAbstract
{
    public abstract void SomeMethod();
}

public abstract class SecondAbstract : FirstAbstract
{
    public abstract override void SomeMethod();
    //?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}

C # derleyicisinin neden "soyut geçersiz kılma" yazmasına izin verdiğini bilmek merak ediyor. Bu gereksiz değil mi? Böyle bir şey yapmak için derleme zamanı hatası olmalı. Bazı kullanım durumlarına hizmet ediyor mu?

İlginiz için teşekkürler.


44
2018-01-18 05:03


Menşei


Bu özelliği birkaç kez kullandım. Kesinlikle kullanım durumları vardır. - ChaosPandion
Bu yardımcı olmalıdır: blogs.msdn.com/b/jmstall/archive/2005/08/07/... - VS1
Neden sadece gereksiz olan bir şey derleme zamanı hatası neden olur? - saus
@saus, çünkü bazı gereksiz şeyler, bir hata veya yanlış anlaşılma ve dolayısıyla bir hata ya da en azından bir uyarının uygun olduğunu öne sürecek kadar saçmadır. public arayüz üyeleri üzerinde bir örnek olurdu. - Jon Hanna
Bir kullanım vakası vardı ve bunu nasıl yapacağımı araştırıyordum, bu da beni bu soruya yönlendirdi. Sorunuz sorumu yanıtladı, teşekkürler! - palswim


Cevaplar:


Bunun için yararlı bir örnek var. MSDN - Temel olarak, türetilmiş bir sınıfı bir yöntem için yeni bir uygulama sağlamak için zorlayabilirsiniz.

public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

Eğer sanal bir yöntem soyut olarak bildirilmişse, yine de sanaltır.   soyut sınıftan miras kalan sınıf. Bir sınıf devralma   soyut yöntem, orijinal uygulamanın   yöntem- önceki örnekte, F sınıfı DoWork DoWork'u arayamaz   D sınıfı. Bu şekilde, soyut bir sınıf türetilmiş sınıfları zorlayabilir.   sanal yöntemler için yeni yöntem uygulamaları sağlamak.


56
2018-01-18 05:08



Ya ben böyle bir şey yapsaydım F ff = new F(); D dd = ff as D; dd.DoWork(0);? Bu çağrı olmaz mıydı? Duygulanması? Ve eğer doğruysa, içine koyabilir miyim F'ler DoWork(int i)gibi bir şey kodu D dd = this as D; dd.DoWork(i);? Bu çağrı mı? Duygulanması? - Blueriver
@Blueriver herhangi bir sanal üye ile olduğu gibi, gerçek nesnenin uygulanmasını çağırır, bu yüzden bu durumda Fuygulanması. - Jon Hanna


Uygunluğu sağlamak için gerçekten faydalı buluyorum ToString() türetilmiş sınıflarda uygulama. Diyelim ki, soyut temel sınıfınız var ve gerçekten türetilmiş sınıfların gerçekten anlamlı olduğunu tanımlamasını istiyorsunuz. ToString() Uygulama aktif olarak kullanıyorsunuz. İle çok zarif yapabilirsiniz abstract override:

public abstract class Base
{
    public abstract override string ToString();
}

Bu uygulayıcılara açık bir sinyal olduğunu ToString() Baz sınıfında bir şekilde kullanılacaktır (kullanıcıya çıktı yazma gibi). Normalde, bu geçersiz kılmayı tanımlamayı düşünmezlerdi.


42
2017-07-21 10:38



Upvoted. Bu, gerçekten bu konuya ait harika bir örnektir. Aynı örnek de verildi başka bir yerde eski bir cevap Karşılaştırma için sadece Taşma Taşması üzerinde. - Jeppe Stig Nielsen


İlginçtir ki, C # derleyicisinin Roslyn sürümünde, hakkında bir makale yazmak için yeterince tuhaf bulduğum soyut bir geçersiz kılma yöntemi vardır:

http://ericlippert.com/2011/02/07/strange-but-legal/


12
2018-01-18 06:45





Bunu düşünün SecondAbstract üç sınıf bir hiyerarşinin ortasındadır ve temelinden bazı soyut yöntemler uygulamak ister. FirstAbstract Çocuğundan uygulanacak başka bir yöntem X ayrılırken ThirdAbstract.

Bu durumda, SecondAbstract yöntem X ile süslemek zorunda abstract bir uygulama sağlamak istemediğinden; aynı zamanda, onu süslemek zorunda override çünkü yeni bir X yöntemini tanımlamamaktadır, fakat X'i çocuğa uygulama sorumluluğunu taşımak istemektedir. Bu nedenle, abstract override.

Genel olarak, modellenen kavramlar abstract ve override ortogonaldir. İlk kuvvetler, bir yöntemi uygulamak için sınıflardan türetilirken, ikincisi, bir yöntemin, bir temel sınıfta belirtildiği gibi değil, aynı olduğunu kabul eder. new bir.

Bu nedenle:

  • ne anahtar kelime: "basit" yöntem
  • abstract sadece: türetilmiş sınıf uygulamalıdır
  • override sadece: temel sınıfta tanımlanan yöntemin uygulanması
  • abstract override: türetilmiş sınıf, temel sınıfta tanımlanan bir yöntemi uygulamalıdır

6
2018-01-18 05:08



Ancak SecondAbstract, X yöntemini hiç içermemelidir, çünkü SecondAbstract soyut bir sınıftır. X'in eklenmesi ve soyut geçersiz kılma olarak dekorasyona alınması, X'in dahil edilmemesiyle eşdeğerdir, bu da OP'nin gereksiz olarak tahmin ettiği şeydir. - saus
Bu demek oluyor mu SecondAbstract Temel sınıfın yöntem X uygulaması ile memnun değil mi? - Eranga


Bu, çocuk sınıfında olamaz çünkü yapılır abstract Temel sınıftaki ile aynı adı taşıyan yöntem. override derleyiciye, temel sınıfın davranışını geçersiz kıldığınızı söyler.

Umarım aradığın şey budur.


0
2018-01-18 05:07





Beyan etmediysen SomeMethodgibi abstract override içinde SecondAbstract, derleyici bu sınıfın yöntemin uygulanmasını içermesini beklerdi. İle abstract override Uygulamadan türetilen bir sınıfta olması gerektiği açıktır. SecondAbstract ve değil SecondAbstract kendisi.

Bu yardımcı olur umarım...


0
2018-01-18 05:09





Bu tasarım deseni Şablon Yöntemi modeli olarak bilinir.

Şablon Yöntemleri Wikipedia sayfası

Basit, yazılım dışı bir örnek: Bir dizi askeri birim var: tanklar, jetler, askerler, savaş gemileri, vs. Hepsi ortak yöntemlerin uygulanmasına ihtiyaç duyuyorlar ama onları çok farklı bir şekilde uygulayacaklar:

  • Hareket()
  • Saldırı ()
  • Geri çekilmek()
  • Dinlenme()

vb...


0
2018-06-09 18:00