这是一个初学者OOP问题,可能有很多答案,但我无法找到它们。我会试着在这里问,希望有人能解释或指出我正确的方向。
例如,考虑我的MWE,其中RightTriangle
扩展Rectangle
扩展Shapes
。方法semiPerimeter()
是通过调用perimeter()
来实现的。
对于Rectangle
来说一切都很好,perimeter()
和semiPerimeter()
都在那里工作。问题是覆盖Rectangle
perimeter()
的RightTriangle
perimeter()
方法。运行测试时,我收到一个 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
创建的抽象类。