public class Figure{
enum Shape {
RECTANGLE,
CIRCLE
}
// Tag field - the shape of this figure
final Shape shape;
// These field are use only if shape if RECTANGLE
double length;
double width;
// This field is use only if shape is CIRCLE
double radius;
// Constructor for circle
public Figure(double radius) {
shape = Shape.CIRCLE;
this.radius = radius;
}
// Constructor for rectangle
public Figure(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();
}
}
}
這種標簽類的缺點
- 職責不唯一
- 可讀性差
- 內存占用增加了
- 不能將length、width 、radius域設置為final
- 不利于擴展
總結就是一句話:標簽類過于冗長、容易出錯,并且效率低下
abstract class Figure {
abstract double area();
}
class Circle extends Figure {
final double radius;
Circle(double radius) {
this.radius = radius;
}
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;
}
double area() {
return length * width;
}
}
圓形與長方形的共同點在于都有計算面積的能力。
講這種共同的能力放在根類Figure中。
如果還存在其他公用的屬性,也應該放到該類中。
這種方式即為具有類層次。
類層次還有一個好處即可以反映類型之間本質的層次關系。
假如我們現在要加入一種正方形
class Square extends Rectangle {
square(double side) {
super(side, side);
}
}
這種繼承也可以反映現實中正方形屬于長方形一種。
總而言之,標簽類很少有適用的時候。當你想要編寫一個包含顯示的標簽域的類時,應該考慮一下,這個標簽是否可以被取消,這個類是否可以用類層次來代替,當你遇到一個包含標簽域的現有類時,就要考慮將它重構到一個層次結構中去。