Skip to content

Latest commit

 

History

History
81 lines (68 loc) · 2.48 KB

21_11_23_TIL.md

File metadata and controls

81 lines (68 loc) · 2.48 KB

Diamond Problem

위의 사진과 같이 Class B와 C가 A를 상속받고, D가 B와 C를 상속받는 경우 A에서 상속받은 함수 또는 변수들을 B와 C에서 오버라이딩한다면, D에서 이를 출력하였을 때 어떠한 값이 출력되는지에 대한 문제이다.
다이아몬드의 모양과 비슷한 구조이기 때문에 Diamond Problem이라고 명명되었다.


위의 문제를 Java로 구현한다면 다음과 같다.

public class A  {
  public void printHello()  {
    System.out.println("Hello from Class A");
  }
}

public class B extends A{
  public void printHello()  {
    System.out.println("Hello from Class B");
  }
}

public class C extends A{
  public void printHello()  {
    System.out.println("Hello from Class C");
  }
}

public class D extends B, C {
 public static void main(String[] args)  {
  D d = new D();
  d.printHello();
 }

 public void printHello()  {
    System.out.println("Hello from Class D");
  }
}

위의 예제의 경우 'Class cannot extend multiple classes'라는 에러가 발생한다. 그 이유는 Java는 Class의 다중상속을 허용하지 않기 때문이다.
그렇다면 Java는 어떻게 Diamond Problem을 해결하였을까? Java의 경우 Diamond Problem을 Interface와 default method를 사용하여 해결하였다.

public interface A  {
  public default void printHello()  {
    System.out.println("Hello from Class A");
  }
}

public interface B extends A{
  public default void printHello()  {
    System.out.println("Hello from Class B");
  }
}

public interface C extends A{
  public default void printHello()  {
    System.out.println("Hello from Class C");
  }
}

public class D implements B, C {
  public static void main(String[] args) {
    D d = new D();
    d.printHello();
  }

  public void printHello() {
      B.super.printHello();   // 상속을 받는 인터페이스의 이름으로 default method를 명시적으로 재정의해야 한다.
  }
}

// result : Hello from B

위의 예제와 같이 구현이 필요한 함수를 default method로 Interface A, B, C에서 정의하였고, 이를 D에서 다중 상속받았다. 그 후 printHello를 오버라이딩하여 어떤 인터페이스의 default method를 사용할 것인지 명시하여준다. Java는 Java 8이후로 인터페이스를 사용하여 Diamond Problem을 해결하였다.