A family of shapes

Use inheritance so that different shapes can be treated the same way.

What to build

A parent class and three subclasses, and a report that does not need to know which shape it is holding.

Requirements

  • Complete Circle(radius), Square(side) and Triangle(base, height), each extending Shape.
  • Each has an area() method. A triangle's area is half of base times height.
  • Print the shapes from largest area to smallest. Shapes with equal areas stay in input order.
  • Each line is printed by the describe() method of Shape: NAME AREA, with 2 decimal places.

Input

Several lines: circle R, square S or triangle B H.

Output

One line per shape.

Constraints

There are from 1 to 50 shapes. Sizes are positive numbers up to 1000.

Example

Input:

circle 1
square 2
triangle 4 5

Output:

triangle 10.00
square 4.00
circle 3.14

Why it works

describe calls this.area(), and JavaScript finds the right version for each object through the prototype chain. So the sort and the report work for every shape, and a new shape would need no change to them.

Examples

Example 1 · Input
circle 1
square 2
triangle 4 5
Expected output
triangle 10.00
square 4.00
circle 3.14
Example 2 · Input
square 1
Expected output
square 1.00

Hints

Hint 1

Each subclass calls super with its own name, and has its own area() method.

Hint 2

Math.PI is the value of pi, and toFixed(2) gives two decimal places.

Hint 3

Sort a list of shapes with (a, b) => b.area() - a.area().

Solution

Show one correct solution (try it yourself first)
class Shape {
  constructor(name) {
    this.name = name;
  }
  area() {
    return 0;
  }
  describe() {
    return `${this.name} ${this.area().toFixed(2)}`;
  }
}

class Circle extends Shape {
  constructor(radius) {
    super("circle");
    this.radius = radius;
  }
  area() {
    return Math.PI * this.radius ** 2;
  }
}

class Square extends Shape {
  constructor(side) {
    super("square");
    this.side = side;
  }
  area() {
    return this.side ** 2;
  }
}

class Triangle extends Shape {
  constructor(base, height) {
    super("triangle");
    this.base = base;
    this.height = height;
  }
  area() {
    return (this.base * this.height) / 2;
  }
}

const shapes = [];
let line = prompt();
while (line !== null) {
  const [kind, a, b] = line.split(" ");
  if (kind === "circle") shapes.push(new Circle(Number(a)));
  else if (kind === "square") shapes.push(new Square(Number(a)));
  else shapes.push(new Triangle(Number(a), Number(b)));
  line = prompt();
}
shapes.sort((x, y) => y.area() - x.area());
for (const shape of shapes) {
  console.log(shape.describe());
}

Lesson: Classes and prototypes →