Shape 에 Ring(double outer, double inner) 을 추가하세요. 압축 생성자에서 inner < outer 를 검증하고, Main.section5 의 switch 가 컴파일 오류를 내는 것을 확인한 뒤 case 를 추가하세요. area() 는 바깥 원 넓이에서 안쪽 원 넓이를 뺀 값입니다.
public sealed interface Shape permits Circle, Rect, Triangle, Ring { double area(); }
record Ring(double outer, double inner) implements Shape {
Ring { if (inner <= 0 || inner >= outer) throw new IllegalArgumentException("0 < inner < outer"); }
public double area() { return Math.PI * (outer * outer - inner * inner); }
}
// section5 의 switch 에 추가
case Ring(double o, double i) -> "고리 " + o + "/" + i;permits 에 넣지 않으면 Ring 쪽에서 "sealed 계층에 허용되지 않음" 오류가 나고, 넣으면 switch 쪽에서 완전성 오류가 납니다. 두 오류가 "추가할 곳" 을 전부 알려 줍니다.
PaymentResult 에 Refunded(String txId, BigDecimal amount, String reason) 을 추가하고, handle 에서 환불 금액이 10,000원 이상이면 "환불 승인 대기", 미만이면 "환불 완료" 로 나누세요. 해체 패턴과 when 을 쓰세요.
record Refunded(String txId, BigDecimal amount, String reason) implements PaymentResult {}
// permits 에 PaymentResult.Refunded 추가
case PaymentResult.Refunded(String tx, BigDecimal amt, String why) when amt.compareTo(new BigDecimal("10000")) >= 0
-> "환불 승인 대기 " + tx + " (" + why + ")";
case PaymentResult.Refunded(String tx, BigDecimal amt, String why) -> "환불 완료 " + tx;BigDecimal 비교는 compareTo 입니다(중급 07). 가드 case 를 먼저 두어야 합니다.
다음 Java 8 식 코드를 var, record, switch 식, instanceof 패턴으로 다시 쓰세요. 줄 수가 얼마나 줄어드는지 세어 보세요.
public class Money { private final BigDecimal amount; private final String currency;
public Money(BigDecimal a, String c) { amount = a; currency = c; }
public BigDecimal getAmount() { return amount; } public String getCurrency() { return currency; }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Money)) return false;
Money m = (Money) o; return amount.equals(m.amount) && currency.equals(m.currency); }
@Override public int hashCode() { return Objects.hash(amount, currency); }
@Override public String toString() { return "Money{" + amount + " " + currency + "}"; } }
String label(Object o) { if (o instanceof Money) { Money m = (Money) o; if (m.getCurrency().equals("KRW")) return m.getAmount() + "원"; else return m.getAmount() + " " + m.getCurrency(); } return "?"; }record Money(BigDecimal amount, String currency) {}
String label(Object o) {
return switch (o) {
case Money(BigDecimal amt, String cur) when cur.equals("KRW") -> amt + "원";
case Money(BigDecimal amt, String cur) -> amt + " " + cur;
default -> "?";
};
}클래스 8줄이 1줄, 메서드 5줄이 5줄이지만 캐스팅과 중첩 if 가 사라졌습니다. Object 를 받는 switch 는 경우가 무한하므로 default 가 필요합니다.