<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
public abstract class Shape {
	protected double x;
	protected double y;

	public Shape(double x, double y) {
		this.x = x;
		this.y = y;
	}

	/** Displace the shape by (dx, dy) */
	public void translate(double dx, double dy) {
		this.x += dx; this.y += dy;
	}

	/**
         * What you see in practice (something like): Two shapes are equal if
	 * they have the same x and y coordinates
         *
	 * What that really means: Two shapes are equal if they have the same x
	 * and y coordinates, /unless/ they are Circles, in which case they must
	 * have the same radius, or they are Rectangles, in which case they must
	 * have the same width and height, or ...
	 *
	 * A good spec would be: Two shapes are equal if they cover the same set
	 * of points in the plane.
	 *
	 * .equals is very hard to give good specifications for if you consider
	 * the entire class hierarchy.
	 */
	@Override public boolean equals(Object other) {
		if (!(other instanceof Shape))
			// what people usually do:
			return false;
			// a better habit:
			// return super.equals(other)

		// cast is safe because we checked using instanceof
		Shape o = (Shape) other;
		return this.x == o.x &amp;&amp; this.y == o.y;
	}

	/** = the area of this shape. */
	public abstract double getArea();
	
	public static double sumAreas(Shape[] shapes) {
		double result = 0.0;
		for (int i = 0; i &lt; shapes.length; i++)
			result += shapes[i].getArea();
		return result;
	}
	
	public static void main(String[] args) {
		// note shapes can contain both Circles and Rectangles
		Shape[] shapes = new Shape[] {
			new Circle(0.0, 0.0, 1.0),
			new Circle(3.2, 4.4, 1.0),
			// new Shape(1.0, 2.0) is illegal because Shape is
			// abstract; which is good because what would getArea
			// return if we could create a Shape?
			new Rectangle(1.2, 1.2, 3.0, 4.0)
		};

		System.out.println(sumAreas(shapes));
	}
}
</pre></body></html>