본문 바로가기
개발/JAVA

공변반환 타이핑

by 손너잘 2021. 2. 26.

이펙티브 자바의 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이 상속관계일 떄 위와같은 코드가 정상 작동하는걸 생각하면 어렵지 않을것이다.

그럼에도 불구하고, 오버라이드는 무조건 부모의 메소드 패턴을 따라가야 한다고 생각했는데, 공변성을 이용해서 이렇게도 표현이 된다는게 정말 신기하다.

댓글