class Figure {
enum Shape { RECTANGLE, CIRCLE };
// 태그 필드 - 현재 모양을 나타낸다.
final Shape shape;
// 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다.
double length;
double width;
// 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다.
double radius;
// 원용 생성자
Figure(double radius) {
shape = Shape.CIRCLE;
this.radius = radius;
}
// 사각형용 생성자
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(shape);
}
}
- 열거 타입, 태그 필드, switch문 등
- 태그 값에 상관없이 동작이 일정한 메소드는 root 클래스의 일반 메소드로 추가한다.
// 태그 달린 클래스를 클래스 계층 구조로 변환
// 추상 클래스 정의
abstract class Figure {
abstract double area();
}
// root 클래스를 확장한 구체 클래스들
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; }
}
class Square extends Rectangle {
Square(double side) {
super(side, side);
}
}
Reference: