OOP java Stack Overflow from overridden method



这是一个初学者OOP问题,可能有很多答案,但我无法找到它们。我会试着在这里问,希望有人能解释或指出我正确的方向。

例如,考虑我的MWE,其中RightTriangle扩展Rectangle扩展Shapes。方法semiPerimeter()是通过调用perimeter()来实现的。

对于Rectangle来说一切都很好,perimeter()semiPerimeter()都在那里工作。问题是覆盖Rectangleperimeter()RightTriangleperimeter()方法。运行测试时,我收到一个 StackOverflowError,因为semiPerimeter()调用perimeter()而又调用semiPerimeter()

为什么super.semiPerimeter()调用不使用矩形超类中的perimeter()


兆威

形状.java

package ShapesPackage;
public abstract class Shapes {
public abstract double perimeter();
public double semiPerimeter() {
return perimeter() / 2;
}
}

矩形.java

package ShapesPackage;
public class Rectangle extends Shapes {
public double perimeter() {
return 2 * (3 + 4); //2*(length+height)
}
}

直角三角形.java

package ShapesPackage;
public class RightTriangle extends Rectangle {
public double perimeter() {
return super.semiPerimeter() + 5;  //half the rectangle perimeter plus some hypotenuse
}
}

测试.java

package ShapesPackage;
public class Test {
public static void main(String[] args) {
Rectangle r = new rectangle();
System.out.println(r.perimeter());
System.out.println(r.semiPerimeter());
RightTriangle t = new rightTriangle();
System.out.println(t.perimeter());  //Fails
}
}

你的方法 (t.perimeter((( 确实从类中调用semiPerimeter方法Shapes而类又从rightTriangle类调用perimeter,并重复此操作。

请注意,new rightTriangle()基本上意味着return perimeter() / 2将从类中调用perimeter方法rightTriangle

为什么super.semiPerimeter()调用不使用矩形超类中的perimeter()

因为您在重写了perimeter()方法的rightTriangle对象上调用了它。调用perimiter()调用rectangle类是没有意义的,因为它是一个rightTriangle对象。因此,这两种方法不断调用自己,从而导致StackOverflowError

以下是正在发生的事情:

你叫t.perimeter(),它叫super.semiPerimeter()->perimeter()->super.semiPerimeter()等等。

听起来你已经知道这一点了。我相信,当您扩展一个类时,如果您创建一个与父类具有相同签名的方法,则会覆盖它,使任何调用都转到您的覆盖方法而不是原始方法。抽象类调用perimeter是隐式this.perimeter的,什么是this?这是一个rightTriangle.因此,当您的抽象类看到perimeter时,它会看到您用rightTriangle创建的抽象类。

相关内容

最新更新