hpekristiansen
hpekristiansen

Reputation: 1070

OOP java Stack Overflow from overridden method

This is a beginners OOP question, that probably has many answers, but I have not been able to find them. I will try to ask here in the hope that someone can explain or point me in the right direction.

As an example consider my MWE, where RightTriangle extends Rectangle that extends Shapes. The methode semiPerimeter() is implemented by calling perimeter().

All is well for the Rectangle, where both perimeter() and semiPerimeter() works. The problem is the perimeter() methode of RightTriangle which overrides the Rectangle perimeter(). When running the test, I get a StackOverflowError, because semiPerimeter() calls perimeter() that in turn calls semiPerimeter().

Why does the super.semiPerimeter() call not use the perimeter() from the rectangle super class?


MWE

Shapes.java

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

Rectangle.java

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

RightTriangle.java

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

Test.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
    }
}

Upvotes: 0

Views: 82

Answers (3)

GBlodgett
GBlodgett

Reputation: 12819

Why does the super.semiPerimeter() call not use the perimeter() from the rectangle super class?

Because you called it on a rightTriangle object which has overridden the perimeter() method. It would make no sense for the call to perimiter() to call the rectangle class, as it is a rightTriangle object. Because of this, the two methods continually call themselves, resulting in a StackOverflowError

Upvotes: 2

Grey Haven
Grey Haven

Reputation: 380

Here's what's happening:

You call t.perimeter(), which calls super.semiPerimeter() -> perimeter() -> super.semiPerimeter() etc etc etc.

Sounds like you already know this. I believe that when you extend a class, if you create a method with the same signature as the parent class, you override it, making any calls go to your override method instead of the original. The perimeter the abstract class calls is implicitly this.perimeter, and what is this? It's a rightTriangle. So when your abstract class sees perimeter it sees the one you made with rightTriangle.

Upvotes: 1

Swapnil
Swapnil

Reputation: 8318

Your method (t.perimeter()) does call semiPerimeter method from Shapes class, which in turn calls perimeter from rightTriangle class again and this repeats.

Note that new rightTriangle() basically means that return perimeter() / 2 will invoke perimeter method from rightTriangle class.

Upvotes: 3

Related Questions