调用重写的超级方法导致无限递归

Calling an Overridden Super Method Causes Infinite Recursion

我正在编写一个程序,其中被覆盖的方法必须调用父 class 中的方法,而后者又必须调用被覆盖方法的原始方法。被覆盖的方法还必须调用其父方法。

这是我的代码:

public class Cow 
{
  public float hiCat()
  {
    ...
    return meow;
  }

  public float dog()
  {
    float meowz = hiCat();
    ...
  }
}

public class Moo extends Cow
{
  public float hiCat()
  {
    float dogBark = dog();
    float meows = super.hiCat();
    ...
  }
}

这给我一个堆栈溢出错误,如下所示:

Exception in thread "main" java.lang.WhosebugError
at Moo.hiCat(Moo.java:12)
at Cow.dog(Cow.java:63)

Moo 中的第 12 行是 float dogBark = dog();Cow 中的第 63 行是 float meowz = hiCat();

我认为第 63 行是 dog() 中的问题。

似乎 class Moo 中的 hiCat() 正在调用 class Cow 中的 dog() 就像它应该的那样,但是 dog() 正在调用覆盖的版本hiCat() 而不是与它共享 class 的那个。这让我感到困惑,因为我以常规方式调用 hiCat(),没有任何修饰符或任何东西。

为什么会发生这种情况,我该如何解决?

注意:程序的结构必须保持不变。

Main 方法与手头的方法完全无关:

public static void main(String[] args) 
{
    InputClass input = new InputClass();
    input.GenerateGUI();
}

这是因为你在 hiCat() 的覆盖方法中调用 dog(),然后当你执行该方法时,这一行 float dogBark = dog() 调用 dog() 方法在 super class 的 dog() 方法内部再次调用 hiCat(); 并且 hiCat(); 再次调用 dog() 因为 hiCat(); 方法被子 class 然后它会调用被覆盖的 hiCat(); 方法..... 所以 WhosebugError 发生

您在方法之间创建了循环依赖。处理此类情况的最佳方法是重构代码并创建私有方法 _hiCat()

public class Cow 
{

private float _hiCat()
{
   ...
   return meow;
}

public float hiCat()
{
   return _hiCat();
}

public float dog()
{
   float meowz = _hiCat();
   ...
}
}

public class Moo extends Cow
{
 public float hiCat()
{
float dogBark = dog();
float meows = super.hiCat();
...
}
}

这里有一个类似的问题,有正确的解释:Java: Calling a super method which calls an overridden method

我通过将 dog() 中的 meowz 变量更改为 class 变量来解决我的特定问题,然后 hiCat() 可以保存到该变量,从而否定需要从 dog() 调用 hiCat() 并避免无限递归。

请注意,我还在 C# 中对此进行了测试,它确实适用于此设置。好像只有Java有这个问题。