标签类,包含一个标签属性(tag field),表示实例的风格
// Tagged class - vastly inferior to a class hierarchy!
class Figure {enum Shape { RECTANGLE, CIRCLE };// Tag field - the shape of this figurefinal Shape shape;// These fields are used only if shape is RECTANGLEdouble length;double width;// This field is used only if shape is CIRCLEdouble radius;// Constructor for circleFigure(double radius) {shape = Shape.CIRCLE;this.radius = radius;}// Constructor for rectangleFigure(double length, double width) {shape = Shape.RECTANGLE;this.length = length;this.width = width;}double area() {switch(shape) {case RECTANGLE:return length * width;case CIRCLE:return Math.PI * (radius * radius);default:throw new AssertionError(shape);}}
}
总之,标签类是冗长的,容易出错的,而且效率低下。
子类型化(subtyping)
首先定义一个包含抽象方法的抽象类,该标签类的行为取决于标签值。
接下来,为原始标签类的每种类型定义一个根类的具体子类。
// Class hierarchy replacement for a tagged class
abstract class Figure {abstract double area();
}class Circle extends Figure {final double radius;Circle(double radius) { this.radius = radius; }@Override double area() { return Math.PI * (radius * radius); }
}class Rectangle extends Figure {final double length;final double width;Rectangle(double length, double width) {this.length = length;this.width = width;}@Override double area() { return length * width; }
}