0

So I am learning abstract classes in java right now, this one specifically is asking to rewrite a superclass Triangle to be abstract, and have subclasses RightTriangle, EquilateralTriangle that return the ratio of area / perimeter. For some reason, the BlueJ program is throwing an error when I don't use a no-args constructor in the Triangle superclass. When I use it, the code seems to completely ignore the body of the subclasses and returns NaN for both values. Here is the code:

Triangle abstract superclass:

public abstract class Triangle
{
  private double side;

  public Triangle()

  {
     double s;
  }

  public Triangle(double side)
  {
    super();
    this.side = side;
  }

  public double getSide()
  {
      return side;
  }

  public void setSide(double side)
  {
      this.side = side;
  }

  @Override
  public abstract double getPerimeter();

  @Override
  public abstract double getArea();

  @Override
  public abstract double getRatio();

  @Override
  public abstract String toString();



  public static void main(String[] args)

  {
    Triangle equilateralTr = new RightTriangle(12);
    Triangle rightTr = new EquilateralTriangle(12);
    System.out.println(equilateralTr.toString());
    System.out.println(rightTr.toString());
  }

}

RightTriangle Subclass:

public class RightTriangle extends Triangle
{
    public RightTriangle(double s)
    {
      super.getSide();
    }

    public double getSideVal()
    {
      double s = super.getSide();
      return s;
    }

    public double getPerimeter()
    {
      return (2 + Math.sqrt(2.0)) * getSideVal();
    }

    public double getArea()
    {
      return getSideVal() * getSideVal() / 2;
    }

    public double getRatio()
    {
      return getArea() / getPerimeter();
    }

    public String toString()
    {
      return "Right Triangle: " + getRatio();   
    }

}

EquilateralTriangle subclass:

public class EquilateralTriangle extends Triangle
{
    public EquilateralTriangle(double l)
    {
        l = super.getSide();
    }

    public double getSideVal()
    {
      double l = super.getSide();
      return l;
    }

    public double getPerimeter()
    {
      return 3 * getSideVal();
    }

    public double getArea()
    {
      return Math.sqrt(3) / 4 * getSideVal() * getSideVal();
    }

    public double getRatio()
    {
       return getArea() / getPerimeter();
    }

    public String toString()
    {
      return "Equilateral Triangle: " + getRatio();   
    }
}
  • 1
    What's with all the blank lines? Makes code difficult to read. --- What's with the bad indentation? Makes code difficult to read. – Andreas Feb 20 '18 at 04:29
  • Why are there no `@Override` annotations? Makes it difficult to say which methods are supposed to override methods from abstract base class. Try using an IDE. – Andreas Feb 20 '18 at 04:31
  • all the abstract methods are being overridden, also toString methods – Cameron Gould Feb 20 '18 at 04:56

3 Answers3

2

Your no-args constructor in abstract class does nothing. So value of side remains 0.0 when you try to initialize your child classes using it. And in your test you divide by zero and get NaN. And your child classes always use default no-args constructor, as soon as you explicitly does not call any.

Read here about constructors and constructors call hierarchy.

Evgeny
  • 1,760
  • 10
  • 11
1

In this method:

public Triangle()
{
    double s;
}

what do you believe the double s; statement is doing?
Answer: It doesn't do anything.


In this method:

public RightTriangle(double s)
{
  super.getSide();
}

do you believe the parameter is ever used?
Answer: It is not.


In this method:

public EquilateralTriangle(double l)
{
    l = super.getSide();
}

What do you believe is the effect of assigning a value to the parameter here?
Answer: No effect, since parameter variable is never used after being assigned.


So, all-in-all, when you run this:

Triangle equilateralTr = new RightTriangle(12);
Triangle rightTr = new EquilateralTriangle(12);

how did you believe the value 12 would ever be assigned to the side field?

Hint: When the subclass constructor doesn't explicitly call super(), the no-arg base class constructor will be called, so the Triangle(double side) constructor is never called in your code.

You might have noticed this if you had tried debugging your code.

Andreas
  • 154,647
  • 11
  • 152
  • 247
0

There is so much needs to be changed/adapted. Check @ http://tpcg.io/nuJT6h

abstract class Triangle {
    private double side;

    public Triangle(double side) {
        this.side = side;
    }  

    public Triangle() {
        this(0);
    }

    public double getSide() {
        return side;
    }

    public void setSide(double side) {
        this.side = side;
    }

    public abstract double getPerimeter();
    public abstract double getArea();
    public abstract double getRatio();
    public abstract String toString();
}

class RightTriangle extends Triangle
{
    public RightTriangle(double side) {
       super(side);
    }

    @Override
    public double getPerimeter() {
        return (2 + Math.sqrt(2.0)) * getSide();
    }   

    @Override
    public double getArea() {
        return (getSide() * getSide()) / 2;
    }

    @Override
    public double getRatio() {
        return getArea() / getPerimeter();
    }

    @Override
    public String toString() {
      return "Right Triangle: " + getRatio();   
    }
}

class EquilateralTriangle extends Triangle
{
    public EquilateralTriangle(double side) {
        super(side);
    }

    @Override
    public double getPerimeter() {
        return 3 * getSide();
    }

    @Override
    public double getArea() {
        return (Math.sqrt(3) / 4) * getSide() * getSide();
    }

    @Override
    public double getRatio() {
        return getArea() / getPerimeter();
    }

    @Override
    public String toString() {
      return "Equilateral Triangle: " + getRatio();   
    }
}

public class Program {

     public static void main(String []args){
        Triangle equilateralTr = new RightTriangle(12);
        Triangle rightTr = new EquilateralTriangle(12);
        System.out.println(equilateralTr.toString());
        System.out.println(rightTr.toString());
     }
}