java 强制基方法调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3982673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:15:25  来源:igfitidea点击:

Force base method call

c#javainheritancepolymorphismsuper

提问by irwinb

Is there a construct in Java or C# that forces inheriting classes to call the base implementation? You can call super() or base() but is it possible to have it throw a compile-time error if it isn't called? That would be very convenient..

Java 或 C# 中是否有强制继承类调用基本实现的构造?您可以调用 super() 或 base() 但是如果没有调用它是否可能引发编译时错误?那会很方便。。

--edit--

- 编辑 -

I am mainly curious about overriding methods.

我主要对覆盖方法感到好奇。

采纳答案by MStodd

There isn't and shouldn't be anything to do that.

没有也不应该这样做。

The closest thing I can think of off hand if something like having this in the base class:

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

public virtual void BeforeFoo(){}

public void Foo()
{

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

}

public virtual void AfterFoo(){}

And allow the inheriting class override BeforeFoo and/or AfterFoo

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

回答by Cameron Skinner

Not in Java. It might be possible in C#, but someone else will have to speak to that.

不是在 Java 中。这在 C# 中可能是可能的,但其他人必须对此进行讨论。

If I understand correctly you want this:

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

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

class B extends A {
    public void foo() {
        super.foo();
        // Do subclass stuff
    }
}

What you can do in Java to enforce usage of the superclass foo is something like:

你可以在 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
    }
}

It's ugly, but it achieves what you want. Otherwise you'll just have to be careful to make sure you call the superclass method.

这很丑陋,但它实现了你想要的。否则,您只需要小心确保调用超类方法。

Maybe you could tinker with your design to fix the problem, rather than using a technical solution. It might not be possible but is probably worth thinking about.

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

EDIT: Maybe I misunderstood the question. Are you talking about only constructors or methods in general? I assumed methods in general.

编辑:也许我误解了这个问题。你是在谈论一般的构造函数还是方法?我假设了一般的方法。

回答by Lea Hayes

The following example throws an InvalidOperationExceptionwhen the base functionality is not inherited when overriding a method.

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

This might be useful for scenarios where the method is invoked by some internal API.

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

i.e. where Foo()is not designed to be invoked directly:

即 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.");
    }
}

Works:

作品:

public class ExampleA : ExampleBase {
    protected override void Foo() {
        base.Foo();
    }
}

Yells:

喊道:

public class ExampleB : ExampleBase {
    protected override void Foo() {
    }
}

回答by Kemoda

You may want to look at this (call super antipatern) http://en.wikipedia.org/wiki/Call_super

你可能想看看这个(调用超级反模式)http://en.wikipedia.org/wiki/Call_super

回答by Sebastian Piu

If I understand correctly you want to enforce that your base class behaviour is not overriden, but still be able to extend it, then I'd use the template method design pattern and in C# don't include the virtual keyword in the method definition.

如果我理解正确,您想强制您的基类行为不被覆盖,但仍然能够扩展它,那么我将使用模板方法设计模式,并且在 C# 中不要在方法定义中包含 virtual 关键字。

回答by Russell McClure

No. It is not possible. If you have to have a function that does some pre or post action do something like this:

不,这是不可能的。如果您必须有一个执行一些前或后操作的函数,请执行以下操作:

internal class Class1
{
   internal virtual void SomeFunc()
   {
      // no guarantee this code will run
   }


   internal void MakeSureICanDoSomething()
   {
      // do pre stuff I have to do

      ThisCodeMayNotRun();

      // do post stuff I have to do
   }

   internal virtual void ThisCodeMayNotRun()
   {
      // this code may or may not run depending on 
      // the derived class
   }
}

回答by Chris Barker

I didn't read ALL the replies here; however, I was considering the same question. After reviewing what I REALLY wanted to do, it seemed to me that if I want to FORCE the call to the base method that I should not have declared the base method virtual (override-able) in the first place.

我没有阅读这里的所有回复;然而,我正在考虑同样的问题。在回顾了我真正想做的事情之后,在我看来,如果我想强制调用基本方法,我不应该首先将基本方法声明为虚拟(可覆盖)。

回答by Sentinel

Don't force a base call. Make the parent method do what you want, while calling an overridable (eg: abstract) protected method in its body.

不要强制进行碱基检出。让父方法做你想做的事,同时在它的主体中调用一个可覆盖的(例如:抽象的)受保护的方法。

回答by mschmit

I stumbled on to this post and didn't necessarily like any particular answer, so I figured I would provide my own ...

我偶然发现了这篇文章,并不一定喜欢任何特定的答案,所以我想我会提供我自己的......

There is no way in C# to enforce that the base method is called. Therefore coding as such is considered an anti-pattern since a follow-up developer may not realize they must call the base method else the class will be in an incomplete or bad state.

在 C# 中没有办法强制调用基本方法。因此,这样的编码被认为是一种反模式,因为后续开发人员可能没有意识到他们必须调用基方法,否则类将处于不完整或错误状态。

However, I have found circumstances where this type of functionality is required and can be fulfilled accordingly. Usually the derived class needs a resource of the base class. In order to get the resource, which normally might be exposed via a property, it is instead exposed via a method. The derived class has no choice but to call the method to get the resource, therefore ensuring that the base class method is executed.

但是,我发现需要此类功能并且可以相应地实现的情况。通常派生类需要基类的资源。为了获取通常可能通过属性公开的资源,它改为通过方法公开。派生类只能调用获取资源的方法,从而确保执行基类方法。

The next logical question one might ask is why not put it in the constructor instead? The reason is that it may be an order of operations issue. At the time the class is constructed, there may be some inputs still missing.

人们可能会问的下一个合乎逻辑的问题是为什么不把它放在构造函数中呢?原因可能是操作顺序问题。在构建类时,可能还缺少一些输入。

Does this get away from the question? Yes and no. Yes, it does force the derived class to call a particular base class method. No, it does not do this with the override keyword. Could this be helpful to an individual looking for an answer to this post, maybe.

这是否脱离了问题?是和否。是的,它确实强制派生类调用特定的基类方法。不,它不会使用 override 关键字执行此操作。这可能对寻找这篇文章答案的人有帮助吗?

I'm not preaching this as gospel, and if individuals see a downside to this approach, I would love to hear about it.

我不是把这当成福音来宣扬,如果有人看到这种方法的缺点,我很想听听。

回答by pstanton

In java, the compiler can only enforce this in the case of Constructors.

在 java 中,编译器只能在构造函数的情况下强制执行此操作。

A constructor must be called all the way up the inheritance chain .. ie if Dog extends Animal extends Thing, the constructor for Dog must call a constructor for Animal must call a constructor for Thing.

必须在继承链上一直调用构造函数。即,如果 Dog extends Animal extends Thing,则 Dog 的构造函数必须调用 Animal 的构造函数,必须调用 Thing 的构造函数。

This is not the case for regular methods, where the programmer must explicitly call a super implementation if necessary.

这不是常规方法的情况,程序员必须在必要时显式调用超级实现。

The only way to enforce some base implementation code to be run is to split override-able code into a separate method call:

强制运行某些基本实现代码的唯一方法是将可重写代码拆分为单独的方法调用:

public class Super
{
    public final void doIt()
    {
    // cannot be overridden
        doItSub();
    }

    protected void doItSub()
    {
     // override this
    }
}

public class Sub extends Super
{
    protected void doItSub()
    {
     // override logic
    }
}