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());
Być może chciałeś rzucić wzmiankę o wzorze metody szablonów (lub możesz strzelać dla zwięzłości) –
A co ze słowem "wirtualnym" przed metodą DoSomething? – Kamarey
@Kamarey Metoda DoSomething nie jest wirtualna: jest to metoda DoSomethingCore, której oczekuje się, że podklasy będą nadpisywać/implementować. – ChrisW