2014-07-16 11 views
11

Mam abstrakcyjna klasa podstawowa:Dlaczego mogę abstrakcyjne zastąpić metodę abstrakcyjną?

abstract class Foo 
{ 
    virtual void DoSomeStuff() 
    { 
     //Do Some Stuff 
    } 

    abstract void DoSomeCrazyStuff(); 
} 

a inna klasa abstrakcyjna pochodzący z tego:

abstract class Bar : Foo 
{ 
    abstract override void DoSomeStuff(); 

    abstract override void DoSomeCrazyStuff(); 
} 

rozumiem dlaczego chcesz chcą abstrakcyjnego ręcznym DoSomeStuff() - będzie wymagać nowego implementację dalsze pochodne klasy. Ale nie mogę zrozumieć, dlaczego chciałbyś abstrakcyjne zastąpić DoSomeCrazyStuff(). O ile wiem, jest to zbędne - jestem prawie pewien, że usunięcie go będzie miało zerowy negatywny wpływ.

Czy jest jakiś przypadek, w którym abstrakcyjne pomijanie abstrakcji robi coś pożytecznego? Jeśli nie, to dlaczego nie ma ostrzeżenia kompilatora informującego mnie, że to, co napisałem, nic nie robi?

+1

ten link może pomóc - http://msdn.microsoft.com/en-us/library/ms173150%28VS.80%29.aspx – terrybozzio

+3

To należy do kategorii "ponieważ specyfikacja mówi tak". –

+0

Wygląda to na dobre żądanie funkcji dla Roslyn. –

Odpowiedz

3

Dlaczego mogę zastąpić abstrakcję metodą abstrakcyjną?

Na początek nie ma praktycznego powodu, aby temu zapobiec. Jeśli wygeneruje błąd kompilatora, wszystko, co można zrobić, spowoduje, że klasy będą bardziej kruche. Na przykład:

abstract class Foo 
{ 
    virtual void DoSomeStuff() 
    { 
     //Do Some Stuff 
    } 
} 

abstract class Bar : Foo 
{ 
    abstract override void DoSomeStuff(); 
} 

Jeśli korekcja na streszczenie streszczenie było nielegalne, zmieniając DoSomeStuff na Foo do streszczenia będzie teraz zapobiec Bar z kompilacji. Zastąpienie abstrakcyjne jest zbędne, ale nie ma żadnych potencjalnych negatywnych skutków ubocznych, więc kompilator jest w porządku z tym.


Dlaczego nie pojawia się ostrzeżenie kompilatora informujący mnie, że co ja napisałem nic nie robi?

Kompilator generuje ostrzeżenia dla niektórych rzeczy, które stanowią zagrożenie: Metoda bez wyraźnej ukrycia, martwy kod, przy użyciu przestarzałych metod, itd. Jedynym „problemem” zbędnym streszczenie override może wskazywać to, że kod nie był skutecznie pisemny. To nie jest coś, o co kompilator się troszczy.


Czy jest jakiś przypadek użycia gdzie streszczenie przesłanianie na abstrakcyjny robi coś pożytecznego?

Nie funkcjonalnie. Istnieje jednak kilka przypadków użycia, które możesz celowo zrobić:

  • Poprawa "czytelności" kodu. Posiadanie nadmiarowego abstrahowania abstrakcyjnego posłużyłoby jako przypomnienie, że metoda jest abstrakcyjna.
  • Jeśli przyszłe zmiany w klasie bazowej obejmują zapewnienie implementacji wirtualnej, można zapobiegawczo uniemożliwić niektórym klasom dostęp do tej klasy podstawowej.
  • Jeśli nadpisanie abstrakcyjne jest zbędne, ponieważ klasa podstawowa została zmieniona z wirtualnej na abstrakcyjną, można bezpiecznie pozostawić ją samą.
2

jawnie abstract override ing go w Bar upewnić się, że będzie to postrzegane jako abstrakcyjne przez Bar s potomkowie chociaż w przyszłości Foo może zostać zamieniona na non-abstrakcyjne jeden. Pomimo takiej zmiany, potomkowie Bar będą pracować z tą samą umową.

+0

Widzę w tym praktyczną wartość, ale czy nie jest to naruszenie Liskov Substitution? Wszystkie metody działające na 'Foo' i oczekujące konkretnej' DoSomeCrazyStuff' złamie się po przejściu 'Bar'. –

+2

@AustinMullins Bar i DoSomeCrazyStuff są nadal abstrakcyjne, więc nic nie będzie działać na pasku, ale raczej konkretna klasa, która nie będzie się kompilować bez implementacji wszystkich abstrakcyjnych metod. – User

+0

@OndrejTucny Nie potrzebujesz dodatkowego abstrakcyjnego zastąpienia, aby chronić się przed zmianami kontraktu, istniejące przesłonięcia 'Bar' nadal będą nadpisywać wirtualną implementację. Zapobiegawczo uniemożliwia potomkom 'Bar' napisanym PO ZASTOSOWANIU' Foo's zmienia się na wirtualne z dostępu do podstawowej implementacji. Dlaczego uniemożliwić dostęp do metody, która nie została zapisana? Dlaczego nie zapisać tej decyzji, dopóki ta metoda nie zostanie napisana? – User

Powiązane problemy