- 标签类:其中有许多样板代码,包括枚举声明,标签域和条件语句
- 如果要给它添加风格,除了有权限修改源码之外,你还得给每个条件语句都添加一个条件,否则就会在运行时失败
- 标签类过于冗长,容易出错,并且效率低下
- 我们可以用类层次类代替标签类 – 子类型化
public class Figure {
enum Shape{RECTANGLE,CIRCLE};
final Shape shape;
double width;
double length;
double radius;
Figure(Double radius){
shape = Shape.CIRCLE;
this.radius = radius;
}
Figure(double width,double length){
shape = Shape.RECTANGLE;
this.width = width;
this.length = length;
}
double area(){
switch(shape){
case RECTANGLE:
return width*length;
case CIRCLE:
return Math.PI*(radius*radius);
default:
return 0;
}
}
}
如何将一个标签类优化为类层次 – 子类型化
1.为标签类中的每个方法都定义一个包含抽象方法的抽象类,这些方法的行为都依赖于标签值
2.为每种原始标签类都定义根类的具体子类
Figure类对应的类层次
/**
* 子类型化:定义能表示多种风格对象的单个数据类型,标签类是对其的一种效仿
*/
public abstract class Figure {
abstract double area();
}
public class Circle extends Figure {
final double radius;
Circle(double radius) {
this.radius = radius;
}
@Override
double area() {
return Math.PI * (radius * radius);
}
}
public 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;
}
}
最后扩展:类层次可以用来反映类型之间本质上的层次关系,有助于灵活性,并且进行更好的编译检查
如:正方形本质上也是一种矩形,在类中如何反应?
public class Square extends Rectangle {
// Square(double length, double width) {
// super(length, width);
// // TODO Auto-generated constructor stub
// }
Square(double side) {
super(side, side);
}
}
总结:标签类很少有适用的时候.当你想要编写一个包含显示标签域的类时,应该考虑一下,这个标签是否可以被取消,这个类是否可以用类层次来代替.当你遇到一个包含标签域的现有类时,就要考虑它重构到一个层次结构中去.