상위 클래스 보다는 인터페이스를...
AJN의 AgileJava 4th 스터디에서 Head First Java를 가지고 스터디하고 있습니다. 이번주는 7, 8, 9장을 다룰 것 같은데 7장을 열자마자 이상함을 느꼈습니다.
해당 챕터의 주제가 "상속과 다형성" 이다보니 상속을 이야기 하기 위해 여러 예제를 보여주며 설명하고 있는데 대부분의 예제의 상위 클래스가 제가 보기엔 클래스로 정의하기에는 상당히 추상적이라 인터페이스로 선언하는 것이 맞게 보입니다.
Shape 이라는 클래스에 rotate()와 playSound() 메소드가 정의되어 있고 이 클래스를 상속한 Square, Circle, Triangle, Amoeba 클래스가 있습니다.
도대체 Shape 클래스에 있는 메소드들은 어떻게 구현을 하는 걸까요? 흠;;
상위 클래스는 아래에서 위로 만들어져야 자연스러운 것 같습니다. 반대로 위에서 아래로 구조가 만들어 질 떄는 인터페이스가 어울립니다.
상속 구조는 하위 클래스들 간에(아직 자신이 하위 클래스인줄 모르는 상태에서) 공통되는 코드가 있을 때 그것을 제거하기 위해서 상위클래스가 만들어져야 합니다. 그래야 상위클래스가 쓸모가 있어집니다. 안그럼 위처럼 멍하니 하는일이 애매한 상위클래스가 만들어집니다.
반대로 인터페이스는 애초에 다른 컴포넌트와의 약속을 위해 미리 정해 놓을 수도 있고 이 인터페이스를 구현하는 클래스에 반드시 있어야할 메소드들을 강제 할 수 있기 때문에 미리 인터페이스를 설계 해두고 클래스들이 구현하도록 할 수 있습니다. 물론 매우 자연스러운 현상이며 나중에 필요로 인해 인터페이스와 클래스들 사이에 추상 클래스가 들어설 수도 있겠습니다. 그때가 되면 아래와 같이 바뀔 것입니다.
이러한 구조로 가더라도 결국 다형성은 사용할 수 있게 되며 필요에 따라 Shape 인터페이스를 구현하여 확장할 수도 있으며 AbsractShape을 상속 받아서 구현할 수도 있기 때문에 확장성은 더욱 좋아집니다.
새로운 기능의 추가을 추가 한다고 했을 때에도 새로운 메소드를 가진 인터페이스를 구현하도록 추가만 하면 되는 반면에 상속 구조에서는 상위 클래스를 수정해야 하고, 그렇게 되면 하위 클래스들 중에는 원치 않는데도 상위 클래스의 메소드를 가지게 되는 경우가 발생할 수 도 있습니다.
이래저래 애초부터 상위클래스를 계획하지 말고 처음에는 인터페이스 기반으로 설계를 하고 상위클래스는 필요에 따라 뽑아 내는 것이 그럴싸해 보입니다.