'상속'에 해당되는 글 1건

  1. 2011.01.07 SWT의 사정 - 위젯 상속을 불허하는 이유 1

이 글은 SWT, the standard widget toolkit의 챕터1 섹션2의 내용을 일부 발췌하여, 이해하기 쉽게끔, 의미상으로 번역되고 편집되었습니다.

연약한 부모 문제

객체지향 언어에서 상속은, 소위 *연약한 부모 문제*라는 문제 때문에, 완벽하게 안전하다고 볼 수 없습니다.

*연약한 부모*라는 말은 C++세계에서 유래 했는데, 보통은 부모 클래스에 새로운 메서드나 필드를 추가하면, 그를 원래부터 상속받던 자식 클래스들이 모두 재 컴파일하기 전까지 작동하지 않거나, 메모리 할당량이 부정확해지던 문제를 지칭합니다.

자바의 경우 부모 클래스가 바뀌더라도, 네임 룩업 매커니즘이 알아서 정적인 클래스 호환문제를 자동으로 해결합니다. 심지어 개발자는 그 존재조차 알 필요가 없습니다. 그러나 연약한 부모 문제는 다이나믹한 영역도 가지고 있습니다.

예를 들어 자식 클래스는 부모 클래스가 내부 구현상으로 호출해줄 public 메서드를 오버라이드하여 확장되었을 수 있습니다. 이경우 정적인 클래스 스키마 뿐 만 아니라, 그 메서드를 호출 해 줄 것이라는 *사실*에 근거하여 확장이 이루어 진 것입니다. 그런데 부모 클래스의 구현이 변경되어 더이상 그 메서드를 호출해 주지 않는다면, 정적인 컴파일에는 문제가 없지만, 오작동하게 될 것입니다. 이런 경우 문제를 찾아내는 것은 매우 고된일이 될 것입니다.

SWT는 플랫폼 별 내부구현이 매우 다르고, 변화의 속도가 빠르기 때문에, 부모 클래스가 어떻게 작동한다 하는 *사실*에 근거하여 상속했다가는 큰 낭패를 볼 수 있습니다. 이러한 이유로 SWT의 위젯 클래스들은 임의 상속을 허용하지 않습니다.

강제 임시 상속

보통은 금지 되어있는상속을 꼭 받아야 하겠다면, 위젯의 checkSubclass()를 오버라이드 해야 합니다. 이 메서드는 기본적으로 허가된 확장이 아닐 경우 SWTException을 던지며, 생성된 직후에 호출 됩니다. 아래는 Label을 상속받아 setText를 오버라이드 한 예입니다:

Label label = new Label(shell, SWT.NONE) {
    protected void checkSubclass() {
        // 아무일도 안하게 오버라이드 함.
    }

    public void setText(String string) {
        System.out.println("Setting the string");
        super.setText(string);
    }
};

자바는 class 앞에 final이라는 키워드를 이용하여 간단하게 상속이 불가능하다고 태깅할 수 있습니다. 사실 아주 예전의 SWT는 이 키워드를 사용했습니다. 불행하게도, 이 방법은 지나치게 유연성이 부족함이 증명되었습니다. 특정한 경우 SWT의 클래스에서 에러가 발생되더라도, 개발자들이 이를 우회할 방법이 없었던 것입니다. 개발자는 임시 상속을 통한 패치나, 버전 호환성을 위한 트릭을 사용할 수 없이, 하염없이 SWT팀이 문제를 수정하고 릴리즈 할 때까지 기다려야 했습니다.

이러한 이유로 SWT 위젯들은, 다소 이상해 보이는 상속 제약이 있지만, 이러한 뒷 배경이 있습니다.

Posted by 지이이이율
,