强制基本方法调用
Java或C#中是否有强制inheritance类来调用基础实现的构造? 你可以调用super()或base()但是如果没有调用它可能会抛出编译时错误吗? 那会很方便..
– 编辑 –
我主要是对重写方法感到好奇。
没有也不应该做任何事情。
如果在基类中有这样的东西,我可以想到最接近的事情:
public virtual void BeforeFoo(){} public void Foo() { this.BeforeFoo(); //do some stuff this.AfterFoo(); } public virtual void AfterFoo(){}
并允许inheritance类覆盖BeforeFoo和/或AfterFoo
不是Java。 它可能在C#中,但其他人将不得不说。
如果我理解正确你想要这个:
class A { public void foo() { // Do superclass stuff } } class B extends A { public void foo() { super.foo(); // Do subclass stuff } }
您可以用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 } }
这很难看,但它可以达到你想要的效果。 否则你只需要小心确保调用超类方法。
也许你可以修改你的设计来解决问题,而不是使用技术解决方案。 这可能是不可能的,但可能值得考虑。
编辑:也许我误解了这个问题。 您是否只谈论构造函数或方法? 我总体上假设了方法。
如果我理解正确你想要强制你的基类行为没有被覆盖,但仍然能够扩展它,那么我将使用模板方法设计模式,并且在C#中不包括方法定义中的virtual关键字。
你可能想看看这个(调用super antipatern) http://en.wikipedia.org/wiki/Call_super
以下示例在重写方法时未inheritance基本function时抛出InvalidOperationException
。
这可能对某些内部API调用该方法的情况很有用。
即Foo()
不能直接调用的地方:
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."); } }
作品:
public class ExampleA : ExampleBase { protected override void Foo() { base.Foo(); } }
破口大骂:
public class ExampleB : ExampleBase { protected override void Foo() { } }
不,这是不可能的。 如果你必须有一个function,做一些前或后动作做这样的事情:
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 } }
我没有在这里阅读所有回复; 但是,我正在考虑同样的问题。 在回顾了我真正想要做的事情之后,在我看来,如果我想强制调用基本方法,我不应该首先声明基本方法虚拟(覆盖能力)。
不要认为内置任何可行的解决方案。 不过,我确信有单独的代码分析工具可以做到这一点。
编辑误读构造为构造函数。 因为它适合问题的一个非常有限的子集,所以作为CW离开。
在C#中,您可以通过定义在基类型中至少有一个参数的单个构造函数来强制执行此行为。 这将删除默认构造函数并强制派生类型explcitly调用指定的基数,否则会出现编译错误。
class Parent { protected Parent(int id) { } } class Child : Parent { // Does not compile public Child() {} // Also does not compile public Child(int id) { } // Compiles public Child() :base(42) {} }
在java中,编译器只能在Constructors的情况下强制执行此操作。
必须在inheritance链中一直调用构造函数。即如果Dog扩展Animal extends Thing,Dog的构造函数必须调用Animal的构造函数,必须为Thing调用构造函数。
常规方法不是这种情况,程序员必须在必要时显式调用超级实现。
强制执行某些基本实现代码的唯一方法是将可覆盖的代码拆分为单独的方法调用:
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 } }
我偶然发现了这个post,并不一定喜欢任何特定的答案,所以我想我会提供自己的……
C#中没有办法强制调用基本方法。 因此,编码被认为是反模式,因为后续开发人员可能没有意识到他们必须调用基本方法,否则该类将处于不完整或不良状态。
但是,我发现需要这种类型的function并且可以相应地实现的情况。 通常,派生类需要基类的资源。 为了获得通常可能通过属性公开的资源,它通过方法公开。 派生类别无选择,只能调用该方法来获取资源,从而确保执行基类方法。
人们可能会问的下一个逻辑问题是为什么不把它放在构造函数中呢? 原因是它可能是一个操作顺序问题。 在构建类时,可能仍有一些输入缺失。
这是否远离了这个问题? 是的,不是。 是的,它确实强制派生类调用特定的基类方法。 不,它不会使用override关键字执行此操作。 这可能对寻找这篇文章答案的个人有所帮助。
我不是在宣传这个作为福音,如果个人看到这种方法的缺点,我很乐意听到它。
不要强制进行基本呼叫。 使父方法执行您想要的操作,同时在其主体中调用可覆盖(例如:抽象)的受保护方法。