Item 20. 태그 달린 클래스 대신 클래스 계층을 활용하라.

예를 들어, 아래와 같이 태그를 사용하여 원(circle)도 있고, 사각형(ractangle)도 있는 클래스를 정의할 수 있다.

class Figure {
	enum Shape { CIRCLE, RACTANGLE };
	
	// 어떤 모양인지 나타내는 태그 필드
	final Shap shap;
	
	// 태그가 CIRCLE일 때만 사용하는 필드
	double radius;
	
	
	// 태그가 RACTANGLE일 때 만 사용하는 필드
	double length;
	double width;
	
	// CIRCLE일 때만 사용하는 생성자
	Figure(double radius){
		shape = Shape.CIRCLE;
		this.radius = radius;
	}
	
	// RACTANGLE일 때만 사용하는 생성자
	Figure(double length, double width){
		shape = Shape.RACTANGLE;
		this.length = length;
		this.width = width;
	}
	
	double area(){
		switch(shape){
			case CIRCLE:
				return Math.PI * (radius * radius);
			case RACTANGLE:
				return length * width;
			
		}
	}
}
abstract class Figure {
	abstract double area();
}

class Circle extends Figure{
	private double radius;
	public Circle(double radius){
		this.radius = radius;
	}
	public double area(){
		return Math.PI * (radius * radius);
	}
}

class Ractangle extends Figure{
	private double length;
	private double width;
	
	public Ractangle(double length, double width){
		this.length = length;
		this.width = width;
	}
	public double area(){
		return length * width;
	}
}

클래스를 계층으로 구성하면, 단순하고 명료하며 태그 기반 클래스에 있던 난잡하고 상투적인(boilerplate)코드가 사라진다.