强制基本方法调用

irw*_*inb 24 c# java polymorphism inheritance super

Java或C#中是否有强制继承类来调用基础实现的构造?你可以调用super()或base()但是如果没有调用它可能会抛出编译时错误吗?那会很方便..

- 编辑 -

我主要是对重写方法感到好奇.

MSt*_*odd 19

没有也不应该做任何事情.

如果在基类中有这样的东西,我可以想到最接近的事情:

public virtual void BeforeFoo(){}

public void Foo()
{

this.BeforeFoo();
//do some stuff
this.AfterFoo();

}

public virtual void AfterFoo(){}
Run Code Online (Sandbox Code Playgroud)

并允许继承类覆盖BeforeFoo和/或AfterFoo

  • 您的建议似乎是问题的常见解决方案.虽然让它强制(或自动调用它)继承类来调用它会很方便,并且会使某些错误很容易找到.你能详细说明为什么*不应该*有任何功能吗?它是否违反了基本的多态概念,如果是的话,为什么呢? (5认同)
  • “而且不应该有任何事情可以做到这一点。” 当然应该有,就像抽象类强制重写或接口强制方法实现一样。这是一个普遍的需求,如果实施的话,不会把水搅浑。 (3认同)
  • 我没有看到它的限制,如果你有一个类必须调用基本方法作为设计选择,如果基本方法调用是可选的,那么你不使用强制基本调用的假设关键字.如果必须始终调用基本方法没有异常,我不会看到它的限制因为设计师专门选择它是这样的. (2认同)

Cam*_*ner 9

不是Java.它可能在C#中,但其他人将不得不说.

如果我理解正确你想要这个:

class A {
    public void foo() {
        // Do superclass stuff
    }
}

class B extends A {
    public void foo() {
        super.foo();
        // Do subclass stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以用Java来强制使用超类foo,如下所示:

class A {
    public final void foo() {
        // Do stuff
        ...
        // Then delegate to subclass
        fooImpl();
    }

    protected abstract void fooImpl();
}

class B extends A {
    protected void fooImpl() {
        // Do subclass stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

这很难看,但它可以达到你想要的效果.否则你只需要小心确保调用超类方法.

也许你可以修改你的设计来解决问题,而不是使用技术解决方案.这可能是不可能的,但可能值得考虑.

编辑:也许我误解了这个问题.你是在谈论一般的构造函数或方法吗?我总体上假设了方法.

  • +1:我觉得它不丑.这是模板方法模式和正确的方法.名称fooImpl()很难看,但这只是一个例子...... (2认同)

Fid*_*del 7

我使用以下技术。请注意,该Hello()方法是受保护的,因此无法从外部调用它......

public abstract class Animal
{
    protected abstract void Hello();

    public void SayHello()
    {
        //Do some mandatory thing
        Console.WriteLine("something mandatory");

        Hello();

        Console.WriteLine();
    }
}

public class Dog : Animal
{
    protected override void Hello()
    {
        Console.WriteLine("woof");
    }
}

public class Cat : Animal
{
    protected override void Hello()
    {
        Console.WriteLine("meow");
    }
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

static void Main(string[] args)
{
    var animals = new List<Animal>()
    {
        new Cat(),
        new Dog(),
        new Dog(),
        new Dog()
    };

    animals.ForEach(animal => animal.SayHello());
    Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

其产生:

在此输入图像描述


Lea*_*yes 5

以下示例InvalidOperationException在覆盖方法时未继承基本功能时抛出。

这对于方法由某些内部 API 调用的场景可能很有用。

即 whereFoo()不是设计为直接调用的:

public abstract class ExampleBase {
    private bool _baseInvoked;

    internal protected virtual void Foo() {
        _baseInvoked = true;
        // IMPORTANT: This must always be executed!
    }

    internal void InvokeFoo() {
        Foo();
        if (!_baseInvoked)
            throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
    }
}
Run Code Online (Sandbox Code Playgroud)

作品:

public class ExampleA : ExampleBase {
    protected override void Foo() {
        base.Foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

喊道:

public class ExampleB : ExampleBase {
    protected override void Foo() {
    }
}
Run Code Online (Sandbox Code Playgroud)