重写方法的OOP Java堆栈溢出

时间:2018-10-16 17:42:14

标签: java oop methods

这是一个初学者的OOP问题,可能有很多答案,但我一直找不到。我将尝试在这里提出要求,希望有人可以向我解释或指出正确的方向。

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

Rectangleperimeter()都可以正常工作的semiPerimeter()一切都很好。问题是perimeter()的{​​{1}}方法覆盖了RightTriangle Rectangle。运行测试时,我收到一个StackOverflowError,因为perimeter()调用semiPerimeter(),而后者依次调用perimeter()

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


MWE

Shapes.java

perimeter()

Rectangle.java

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

RightTriangle.java

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

Test.java

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

3 个答案:

答案 0 :(得分:3)

您的方法(t.perimeter())确实从semiPerimeter类调用了Shapes方法,而该方法又从perimeter类调用了rightTriangle并且重复了。 / p>

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

答案 1 :(得分:2)

  

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

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

答案 2 :(得分:1)

这是正在发生的事情

您呼叫t.perimeter(),后者呼叫super.semiPerimeter()-> perimeter()-> super.semiPerimeter()等,等等。

像您这样的声音已经知道了。我相信,在扩展类时,如果创建一个与父类具有相同签名的方法,则将其覆盖,从而使所有调用都转到覆盖方法,而不是原始方法。抽象类调用的perimeter是隐式this.perimeterthis是什么?这是rightTriangle。因此,当您的抽象类看到perimeter时,就会看到您用rightTriangle制作的那个。