이펙티브 자바의 builder 패턴을 읽다가 발견했다. 지금까지 모르고 있었는데 정말 신기한 기법이다.
자바의 변수가 "공변" 임을 이용하는 기법인데 소스를 보면서 확인하자
public class Main {
abstract static class Test {
int a = 1;
public int getA() {
return a;
}
abstract public Test ret();
}
static class T extends Test {
int b = 2;
public int getB() {
return b;
}
@Override
public T ret() {
return new T();
}
}
public static void main(String[] args) {
T t = new T();
t.getA();
t.getB()
}
}
Test 클래스에는 Test를 반환하도록 추상함수 ret 가 정의되어 있다.
하지만 Test의 하위 클래스인 T에서 ret을 구현할 때, 반환형을 자기 자신인 T로 반환시켜 Override시킨다.
처음보면 머리에 물음표가 띠어지지만 생각해보면 어려운 개념이 아니다.
상속관계는 is-a 관계로 이루어진다(공변성에 의해). 따라서 T extends Test 는 T is Test 가 성립하는 것이다.
즉, T는 Test이기 때문에 Test대신의 하위타입인 T를 반환하더라도 문제가 없는 것이다.
Animal animal = new Cat();
Cat과 Animal이 상속관계일 떄 위와같은 코드가 정상 작동하는걸 생각하면 어렵지 않을것이다.
그럼에도 불구하고, 오버라이드는 무조건 부모의 메소드 패턴을 따라가야 한다고 생각했는데, 공변성을 이용해서 이렇게도 표현이 된다는게 정말 신기하다.
'개발 > JAVA' 카테고리의 다른 글
캡슐화란 무엇인가? 어떤 이점이 있는가? (19) | 2021.02.18 |
---|---|
알고리즘 문제는 Stream을 사용해서 풀면 안되는 걸까? (3) | 2021.02.17 |
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 오류 해결법 (0) | 2018.02.12 |
댓글