티스토리 뷰

Item20의 핵심은 한 줄로 요약된다

자바에서는 다중 상속이 되지 않기 때문에 추상 클래스보다는 인터페이스를 사용해야 한다

다중 상속을 허용하게 되면 다이아몬드 상속 문제를 피할 수 없다

그럼 다이아몬드 상속 문제가 무엇일까?

 

https://www.tutorialspoint.com/what-is-diamond-problem-in-case-of-multiple-inheritance-in-java

 

아하 Super1, Super2를 다중 상속받았을 때 어떤 놈의 메서드가 우선순위를 가져야 하는지 정하지 못하기 때문이로구나

어떤 계층이 위에 있는지, 어떤 놈이 먼저 나오는지 ex) extends Super1, Super2 이면 Super1의 메서드 상속

식으로 풀어도 되긴 하지만 결국 복잡성이 올라가는 문제를 안고 있다, 애초에 될 수 없게 하는게 간단하다

 

그럼 여러개를 가질 수 있는 방법이 없단 말인가?

다중 상속은 안 되지만 다중 구현은 가능하다

implements SuperInterface1, SuperInterface2으로 만들고 메서드를 구현하면 된다

단 Interface의 default 메서드 또한 다중 상속을 피해 갈 수 없으니 같은 시그니처를 갖고 있는

default method는 컴파일 에러로 잡힌다

 

 

위와 같은 상황일 때는 두 인터페이스 중 하나의 메서드 시그니처를 바꿔주던지

구현 클래스에서 재정의를 통해 구현을 정해주면 된다

 

인터페이스를 사용해야 하는 이유를 하나 더 보자면

다중 상속이 지원 되지 않기 때문에 추상 클래스를 이용하면 타입 정의 시 골치 아파진다

책의 예제처럼 기존 클래스에 새로운 타입을 추가하고자 할 때 추상 클래스를 이용하는 순간

기존 클래스는 추상 클래스의 하위 타입으로 굳어져 버린다

이 말은 새로운 추상 클래스를 상속받도록 변경해야 할 때 기존 클래스의 무지막지한 변화가 필요함을 의미한다

 

그런 무지막지한 변화를 용납할 수 없다면 기존 추상 클래스와 새로운 추상 클래스를 적절히 짬뽕한

새로운 추상 클래스를 만들고 이 녀석을 상속 받아 해결해야 하는데

상상력을 발휘해 이런 오묘한 녀석들이 계속해서 필요하다고 하는 경우, 이를 조합 폭발이라 칭한다

 

반면 인터페이스를 이용했다면 기존 클래스에 새로운 인터페이스를 추가하고 메서드를 구현하면 끝이다

변경이 어떻게 필요할지 예상할 수 없고, 클래스에서는 오직 한 번의 extends만 허용하니 최대한 아껴놔야 한다

특히 프레임워크와 함께 사용할 때 문제가 심화될 수 있다

스프링의 경우 특정 메커니즘을 위해 반드시 상속으로 구현해야 할 때가 있다

물론 상위 인터페이스의 수 많은 메서드를 직접 구현하겠다면 말리지 않는다만..

복잡성을 쉽게 관리하기 위해 필수적으로 인터페이스를 사용해 구현하도록 하자

댓글
링크
글 보관함
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Total
Today
Yesterday