[Java, 다이아몬드 문제] Java에서 다중 상속을 지원 못하는 이유

김우진·2021년 11월 8일
1

상속(Inheritance)

상속은 자식 클래스가 부모 클래스로부터 필드와 메서드를 물려받아 변경하거나 확장하는 것을 말한다.

다이아몬드 문제(Diamond of Death 현상)

public abstract class Person {
    public abstract void getNation();
}
public class Mother extends Person {
    @Override
    public void getNation() {
        System.out.println("My nation is Korea.");
    }
}
public interface Father extends Person {
    @Override
    public void getNation() {
        System.out.println("My nation is USA.");
    }
}
public class Child extends Mother,Father {
    public void myNation() {
        getNation();
    }
}

위와 같은 상황에서 Child 클래스의 myNation()을 실행할 때 컴퓨터는 Child 클래스의 상위 클래스인 Mother 혹은 Father 클래스에서 getNation()을 찾는데 두 상위 클래스 모두 getNation() 메소드를 가지고 있어 Mother의 getNation()을 실행해야할 지 Father의 getNation()을 실행해야할 지 알 수 없다.

그럼 interface는?

public interface Mother {
    public void getNation();
}
public interface Father {
    public void getNation();
}
public interface Child extends Mother, Father {
    public void getNation();
}

인터페이스는 실질적인 구현이 이루어지지 않고 메소드에 대한 선언만 하고 있기 때문에 위와 같이 가능하다.
위처럼 메소드가 겹치더라도 최종 구현 부분은 구현 객체에서 이루어질 것이기 때문에 interface는 다중 상속이 가능하다.

그렇기 때문에 다중상속이 필요한 경우 인터페이스의 다중 상속을 이용해 구현한다.

interface도 다중 상속이 안될 수 있다? (feat. default Method)

default Method

Java8 이상부터 나온 기능으로 메소드 선언 시에 default를 명시하게 되면 인터페이스 내부에서도 로직이 포함된 메소드를 선언할 수 있다.

public interface defaulInterface { 
    default void defaultMethod() {
        System.out.println("default Method 실행")
    }
}

이렇듯 default 키워드를 통해서 인터페이스 내부에 로직 코드가 들어가는 경우, 위의 다이아몬드와 똑같은 문제가 발생할 수 있으므로 Interface 다중 상속 역시 지원하지 않는다.(지원하지 않거나 중복 메서드를 무조건 오버라이딩 해주어야 한다.)

굳이 사용해야 될 이유가 있나?

Default Method가 나온 이유는 "하위 호환성" 때문이다.

예를 들어, 컴퓨터로 제어되는 자동차 제조업체가 자동차에 비행과 같은 새로운 기능을 추가하면 이 제조업체는 다른 회사가 소프트웨어를 하늘을 나는 자동차에 적용할 수 있도록 하는 새로운 방법을 지정해줘야 한다. 이때, 원래의 인터페이스에 이 방법을 추가하게 되면 해당 인터페이스를 구현한 프로그래머는 인터페이스 구현체를 다시 작성해야 한다. 이러한 문제를 해결하기 위해 Java8부터 Default Method를 지원하기 시작했다.

즉, 기존에 존재하던 인터페이스를 이용해서 구현된 클래스들을 만들고 사용하고 있는 중 인터페이스를 보완하는 과정에서 추가적으로 구현해야할 필수적인 메소드가 생긴다면, 이미 이 인터페이스를 구현한 클래스와는 호환성이 떨어 지게 된다.

따라서 default 메소드를 추가하여 필수적으로 구현해야 할 메소드를 정의하면 하위 호환성은 유지시키며 인터페이스를 보완할 수 있다.

출처

  1. oracle docs : java tutorial의 interface, inheritance, multiple Inheritance, Default Methods
  2. siyoon210님의 blog : 자바의 Default Method (디폴트 메소드)
  3. 키가 크고픈 프로그래머님의 blog : [자바]extends와 implements의 차이점
  4. 프로그래머스 자바 입문 수업 : 인터페이스의 default 메소드

0개의 댓글