2009-08-25 9 views
5

Mając coś takiego to:Jak zaimplementować klasę podstawową za pomocą metody, a mimo to wymusić zastąpienie klasy pochodnej?

public abstract class AAA 
{ 
    protected abstract virtual string ToString() // Error 
    { 
    // Base Stuff 
    } 
} 

public abstract class BBB : AAA 
{ 
    public override string ToString() 
    { 
    // Use base.ToString(); 
    // More Stuff 
    } 
} 

czytam kolejny post (abstract method in a virtual class) wiedźma była całkiem jak moje pytanie, ale istnieje niewielka różnica. Chciałbym, aby AAA.ToString() miał bazowe zachowanie i wymusić klasy pochodnej, aby je przesłonić.

Wiem, że mogłem zrobić coś takiego (przewiń w dół), ale szukałem właściwej drogi.

public abstract class AAA 
{ 
    public abstract string ToString(); 
    protected string ToString2() 
    { 
    // Base Stuff 
    } 
} 

public class BBB : AAA 
{ 
    public override string ToString() 
    { 
    // Use base.ToString2(); 
    // More Stuff 
    } 
} 

Mógłbym też prawdopodobnie uczynić interfejs IAAA i budować moją klasę BBB jak

public class BBB : AAA, IAAA { ... } 

ale nie wygląda dobrze dla mnie.

Odpowiedz

5

Twoje podejście jest zasadniczo właściwy sposób ...

Edit:

Twój "specyfikacja" to:

  1. zachowanie domyślne
  2. Wymagane przesłanianie

Teraz, od aplikacji ucho chcieć „default zachowanie”, aby zawsze być wykonywane, trzeba

public string ToString() 
{ 
    // placeholder for some default behaviour 

    string result = doToString(); 

    // placeholder for some more default behaviour 

    return result; 
} 

protected abstract string doToString(); 

Działa to tylko jeśli wiesz, co klasa bazowa robi w ogóle, i chcą, aby zapewnić realizację przez doToString() w klasie pochodnej. Jest to znane jako wzór projektu Template Method.

Jednakże, jeśli szukasz sposobu na wymagają wdrażająca klasy pochodnej zadzwonić base.ToString() w jego realizacji ToString(), to nie ma sposobu, aby to zrobić. Poprzez zezwolenie na nadpisanie, dajesz pochodną klasową kontrolę nad jego implementacją.

Możesz udokumentować swoją rekomendację, aby zawsze dzwonić pod numer base.ToString(), ale to już wszystko.

Używanie interfejsu definiuje zamówienie publiczne dla twojej klasy. Nie daje to żadnych dodatkowych korzyści w stosunku do wzorca metody szablonów, ponieważ nadal musisz wywodzić się z klasy bazowej, aby uzyskać "domyślną" implementację.

Czy masz jakieś szczegóły dotyczące tego, co próbujesz podać w swojej klasie bazowej jako "domyślne zachowanie"? Może to pomoże znaleźć lepsze rozwiązanie. Patrząc na zadane pytanie, jest to zasadniczo to samo podejście.

+0

Dzięki, Twój edit uświadomiły mi coś ważnego! Nawet jeśli znajdę cudowny sposób na zdefiniowanie ToString() w klasie bazowej i wymuszenie nadpisania w klasie pochodnej, po prostu nie ma mowy, żebym mógł wymusić zastąpienie, aby użyć ToString()! Znalazłem również ten post przez MVP o wymuszaniu przesłonięcia: http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/c25b6477-b990-4284-abaf-801ddf18207c. Thanks again sir. – Tipx

+0

Cieszę się z usług. Ten post jest autorstwa Marca Gravell'a ... jest on dobrze znany również w SO :) –

+0

Jak to się ma do poniższej odpowiedzi OP? – Armbrat

0

Nie, nie można obecnie włączyć funkcji wirtualnej w funkcję abstrakcyjną. Jedynym sposobem na egzekwowanie tego byłoby stworzenie kolejnej funkcji, która jest abstrakcyjna, jak sugerujesz. Jest to prawdopodobnie bardziej odpowiednie podejście (i zgadzam się z tym).

2

Właśnie dowiedziałem się, co zrobić, aby uzyskać dokładnie zachowanie chciałem:

public abstract class AAA 
{ 
    protected abstract string ToStringSpecific(); 
    protected string ToString() 
    { 
    // Base Stuff 
    ... 
    // Use this.ToStringSpecific(); 
    } 
} 

public class BBB : AAA 
{ 
    protected override string ToStringSpecific() 
    { 
    // Specific Stuff 
    } 
} 
+0

Myślę, że powinieneś już zmodyfikować swoje oryginalne pytanie ... – Armbrat

+0

Naprawdę edytuję pytanie (i tytuł), aby pomóc komuś znaleźć ten temat, ale pozwolę sobie na rozwiązanie. (Jeśli nie powinno się tego robić w ten sposób, nie byłoby przycisku "Anwser Your Question") – Tipx

+0

Po prostu ponownie przeczytałem drugą część mojego komentarza i brzmi ona "arogancko". Przepraszam za to, nie chciałem być, i nie mogę edytować komentarza. Przepraszam. – Tipx

Powiązane problemy