class Test { public static void main(String[] args) { Point p1 = new Point(new Number(1), new Number(2)); Point p2 = new Point(new Number(3), new Number(4)); Rectangle r1 = new Rectangle(p1, p2); Point p3 = new Point(new RationalNumber(1, 2), new RationalNumber(3, 1)); Point p4 = new Point(new RationalNumber(3, 2), new RationalNumber(1, 1)); Rectangle r2 = new Rectangle(p3, p4); System.out.println(r1.area()); System.out.println(r2.area()); } } class Rectangle { protected Point topLeft; protected Point bottomRight; public Rectangle(Point topLeft, Point bottomRight) { this.topLeft = topLeft; this.bottomRight = bottomRight; } public String toString() { return "[" + topLeft.toString() + "," + bottomRight.toString() + "]"; } public Number area() { Number length_y = topLeft.getY().minus(bottomRight.getY()).abs(); Number length_x = bottomRight.getX().minus(topLeft.getX()).abs(); return length_y.times(length_x); } } class Point { protected Number x; protected Number y; public Point(Number x, Number y) { this.x = x; this.y = y; } public Number getX() { return x; } public Number getY() { return y; } public String toString() { return "(" + x.toString() + "," + y.toString() + ")"; } } class Number { protected double value; public Number(double value) { this.value = value; } public Number minus(Number other) { return new Number(value - other.value); } public Number times(Number other) { return new Number(value * other.value); } public Number abs() { if (value < 0) { return new Number(-value); } else { return this; } } public String squee() { String s = "squee"; for (int i = 0; i < value; i++) { s += "e"; } return s; } public String toString() { return String.valueOf(value); } } /* Observe that I can EXTEND my program by only APPENDING a new * class for RationalNumber, and then modifying just the main * method. I do not need to modify any prior code, including * either Point or Rectangle. They just work! Asymptotically, * instead of having to modify O(m*n) things when adding n new * things to a language, I only need to modify O(n). */ class RationalNumber extends Number { protected double numerator; protected double denominator; public RationalNumber(double numerator, double denominator) { super(numerator / denominator); this.numerator = numerator; this.denominator = denominator; } public String toString() { return String.valueOf(numerator) + "/" + String.valueOf(denominator); } }