方法必须被覆盖但不是抽象的?

时间:2009-07-07 12:37:49

标签: c# inheritance

我想在基类中实现一个函数,但我也希望它每次都在派生类中被覆盖。所以它更像是“抽象的功能,但有一个身体”。

我在找什么?我在找正确的事吗?

4 个答案:

答案 0 :(得分:14)

如果基类有话要说,但你希望它“每次都被覆盖”,那么我会有一对方法:

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

答案 1 :(得分:3)

如果您的基类在方法中执行某些,但您想确保每个子类都被强制实现该方法的某些部分,那么您需要Template Method pattern,如在Marc Gravell的回答中描述。

无法在基类中提供默认实现,仍然强制子类提供自己的实现。但是,您可以创建一个抽象基类并从中继承以提供默认实现,但要使该具体类密封。

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

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

现在任何从FooBase继承的类都必须实现DoStuff(),但是你有一个默认的实现FooImpl,子类可能不会继承它。

您可能还希望将实现方法的职责委托给单独的类,该类在其构造函数中传递给基类。这叫做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
    }
}

现在不是创建子类Foo,而是创建IFooStrategy接口的新实现,并将它们传递给您的Foo实例。所以你可以这样做:

new Foo(Foo.DefaultStrategy);

new Foo(new DifferentStrategy());

答案 2 :(得分:1)

您正在寻找virtual方法(使用此修饰符来允许覆盖该方法),但您无法强制用户覆盖它。如果你有一个正文,强制这个就没有意义,因为你可以调用base.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
}

答案 3 :(得分:1)

听起来你的基本实现永远不会被调用。你为什么要提供一个没有人可以达到的实现(跳过难以忍受的箍)