2009-07-07 21 views

Odpowiedz

14

Jeśli baza-klasa ma coś do powiedzenia, ale chcesz go przesłonięte „za każdym razem”, to chciałbym mieć parę sposobów:

public void DoSomething() { 
    //things to do before 
    DoSomethingCore(); 
    //things to do after 
} 
protected abstract void DoSomethingCore(); 
+3

Być może chciałeś rzucić wzmiankę o wzorze metody szablonów (lub możesz strzelać dla zwięzłości) –

+0

A co ze słowem "wirtualnym" przed metodą DoSomething? – Kamarey

+1

@Kamarey Metoda DoSomething nie jest wirtualna: jest to metoda DoSomethingCore, której oczekuje się, że podklasy będą nadpisywać/implementować. – ChrisW

1

szukasz sposobu virtual (wykorzystanie ten modyfikator, aby umożliwić przesłonięcie metody), ale nie można wymusić na użytkowniku nadpisania go. Wymuszenie tego nie ma sensu, jeśli masz ciało w każdym razie, ponieważ można po prostu wywołać base.YourMethod() i nie robić nic innego, co robi to samo, co nie przesłonięcie metody w pierwszej kolejności.

public virtual YourMethod() { 
    // your base class code here 
} 

a następnie nadrzędnym metody w innej klasy:

public override YourMethod() { 
    // code to do before the base call 
    base.YourMethod(); 
    // code to do after the base call 
} 
3

Jeśli klasa bazowa robi coś w metodzie, ale chcesz, aby upewnić się, że każda podklasa jest zmuszony do realizacji niektórych część metody, następnie chcesz Template Method pattern, jak opisano w odpowiedzi Marc Gravell.

Nie ma sposobu na zapewnienie domyślnej implementacji w klasie bazowej i wciąż wymuszanie podklas w celu zapewnienia własnej implementacji. Można jednak utworzyć abstrakcyjną klasę bazową i dziedziczyć z niej, aby zapewnić domyślną implementację, ale uczynić tę klasę zamkniętą.

public abstract class FooBase { 
    public abstract void DoStuff(); 
} 

public sealed class FooImpl : FooBase { 
    public override void DoStuff { 
     //default widget-munging code 
    } 
} 

Teraz jakieś zajęcia, które dziedziczą z FooBase musiały wdrożyć DoStuff(), ale masz domyślną implementację FooImpl podklasy, z którego nie może odziedziczyć.

Możesz również preferować przeniesienie odpowiedzialności za wdrożenie metody na oddzielną klasę, która jest przekazywana do klasy bazowej w jej konstruktorze. To się nazywa Strategy pattern.

public sealed class Foo { 
    private IFooStrategy _strategy; 
    public Foo(IStrategy strategy) { 
     _strategy = strategy; 
    } 
    void DoStuff() { 
     _strategy.DoStuff(); 
    } 
    public static IFooStrategy DefaultStrategy { 
     //return singleton instance of the default strategy 
    } 
} 

Teraz zamiast instacji Foo, to zamiast tworzyć nowe implementacje interfejsu IFooStrategy, i przekazać te do instancji Foo. Więc można albo zrobić:

new Foo(Foo.DefaultStrategy); 

lub

new Foo(new DifferentStrategy()); 
1

Brzmi jak implementacji bazowej nie zostanie wywołana. Dlaczego miałbyś chcieć dostarczyć implementację, do której nikt nie może się dostać (przeskakiwanie przez obręcze nie jest trwałe)?

Powiązane problemy