考虑这个 MWE:
public class Base {
public int myRecursiveAlgo(int a) {
if (a == 0) { return 0; }
return a + myRecursiveAlgo(a - 1);
}
}
public class Child extends Base {
public int myRecursiveAlgo(int a) {
return super.myRecursiveAlgo(a) + 1; // modification
}
}
现在,你看,Child::myRecursiveCall()
想要将最终结果调整一。但是,Base::myRecursiveAlgo()
现在由于递归调用被分派到Child::myRecursiveAlgo()
. 如何Base::myRecursiveAlgo()
从 Base 类中显式调用?
在 C++ 中,您可以return a + Base::myRecursiveAlgo(a - 1);
防止调用子类重写方法的变体。
你不能。不可能。
因此,您编写的任何调用您自己的方法之一的代码都需要执行以下操作之一,或者您的代码以尚未可测试的方式被破坏(即等待发生的灾难,非常糟糕):
您将要调用的方法必须是private
, 或包私有的,并且有充分的文档记录,以便在同一包中操作的所有人员都知道它所需的属性。
或者,该方法必须 make final
,或者您的类需要有效final
(如果它是非最终的但所有构造函数都是private
,则它实际上是最终的 - 任何重载只能通过在同一源文件中编写子/兄弟姐妹和大概任何人在那里写作是知道条件或至少负责遵守这些条件)。
或者,您的方法将不依赖于它所拥有的任何属性,或者,它所依赖的属性至少已记录在案,并带有一个注意事项。
或者,让您的可覆盖方法是一种单行,将工作转移到不可覆盖的方法(例如私有方法和/或最终方法)。在那里您需要专门锁定到您的基本实现的属性,请调用帮助程序。当然,这本身就令人困惑:据推测,如果有人决定覆盖该方法,那么在某些情况下根本不会调用他们的覆盖是很奇怪的。
第三个(记录它并祈祷)确实存在 - 例如,您可以自由地为某个类编写不一致的 equals/hashCode 算法,然后使用该类的实例作为 HashMap 中的键,但结果将是奇怪的,用各种 Map 彻底撒谎的方法,以及在意想不到的时间发生的奇怪异常。这大概是决定不阅读 equals/hashCode 的合同要求的明灯。
如果必须,您可以做同样的事情。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句