Метод должен быть переопределен, но не является абстрактным?
Я хочу реализовать функцию в базовом классе, но я также хочу быть переопределены в производных классах каждый раз. Так это больше похоже на "абстрактную функцию, но с телом".
Что я ищу? Я ищу правильную вещь?
4 ответов
Если у базового класса есть что сказать, но вы хотите, чтобы он переопределялся "каждый раз", тогда у меня будет пара методов:
public void DoSomething() {
//things to do before
DoSomethingCore();
//things to do after
}
protected abstract void DoSomethingCore();
если ваш базовый класс что-то в методе, но вы хотите убедиться, что каждый подкласс вынужден реализовать некоторую часть метода, тогда вы хотите шаблон метода шаблона, как описано в ответе Марка Гравелла.
нет способа предоставить реализацию по умолчанию в базовом классе и все же заставить подклассы предоставить свою собственную реализацию. Однако можно создать абстрактный базовый класс и наследовать от него, чтобы обеспечить реализация по умолчанию, но сделайте этот конкретный класс запечатанным.
public abstract class FooBase {
public abstract void DoStuff();
}
public sealed class FooImpl : FooBase {
public override void DoStuff {
//default widget-munging code
}
}
теперь любые классы, наследующие от FooBase, должны реализовать DoStuff (), но у вас есть реализация по умолчанию FooImpl, от которой подклассы не могут наследовать.
вы также можете предпочесть делегировать ответственность за реализацию метода отдельному классу, который передается базовому классу в его конструкторе. Это называется стратегии шаблон.
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
}
}
теперь вместо подклассов Foo вы вместо этого создаете новые реализации интерфейса IFooStrategy и передаете их своему экземпляру Foo. Так что вы могли бы сделать:
new Foo(Foo.DefaultStrategy);
или
new Foo(new DifferentStrategy());
мы ищем virtual
способ (использовать этот модификатор, чтобы разрешить переопределение метода), но вы не можете заставить пользователя заменить его. Принуждение к этому не имело бы смысла, если у вас есть тело, так как можно просто назвать базу.YourMethod () и ничего не делать, что делает то же самое, что и не переопределение метода в первую очередь.
public virtual YourMethod() {
// your base class code here
}
а затем переопределяющий метод в другом классе:
public override YourMethod() {
// code to do before the base call
base.YourMethod();
// code to do after the base call
}
похоже, что ваша базовая реализация никогда не будет вызвана. Почему вы хотите предоставить реализацию, до которой никто не может добраться (прыжки через обручи не выдерживают)