상속 한 클래스가 다른 클래스의 속성을 상속하는 두 클래스 간의 관계입니다. 이 관계는 extends 키워드를 사용하여 -
로 정의할 수 있습니다.public class A extends B{ }
속성을 상속하는 클래스를 하위 클래스 또는 하위 클래스라고 하고 속성을 상속받는 클래스를 상위 클래스 또는 상위 클래스라고 합니다.
상속에서 상위 클래스 구성원의 복사본이 하위 클래스 개체에 생성됩니다. 따라서 하위 클래스 개체를 사용하여 두 클래스의 구성원에 액세스할 수 있습니다.
여러 유산:
단일, 다중 레벨, 계층, 다중 및 하이브리드와 같은 다양한 유형의 상속을 사용할 수 있습니다.
다중 상속에서는 한 클래스가 여러 클래스의 속성을 상속합니다. 즉, 다중 상속에서는 하나의 자식 클래스와 n개의 부모 클래스를 가질 수 있습니다. Java는 다중 상속(클래스 포함)을 지원하지 않습니다.
다이아몬드 문제
예를 들어 Java가 다중 상속을 지원한다고 가정해 보겠습니다. 이러한 가정하에 다음 예를 고려하십시오.
예시
여기에 Sample이라는 추상 클래스가 있습니다. −
와 같은 추상 메서드 사용public class abstract Sample { public abstract demo(); }
그런 다음 동일한 패키지/폴더에 이 클래스를 확장하고 추상 메서드인 demo()를 구현하려는 두 개의 클래스가 있습니다.
public class Super1 extends Sample{ public void demo() { System.out.println("demo method of super1"); } } public class Super2 extends Sample{ public void demo() { System.out.println("demo method of super2"); } }
우리의 가정에 따르면 Java는 다중 상속을 지원하므로 Super1 및 Super2 클래스를 모두 상속하려고 합니다.
public class SubClass extends Super1, Super2 { public static void main(String args[]) { SubClass obj = new SubClass(); obj.demo(); } }
그런 다음 기본 상속 규칙에 따라 두 demo() 메서드의 복사본을 서브클래스 객체에 생성해야 합니다. 이 복사본은 동일한 프로토타입(이름 및 인수)을 가진 두 메서드가 있는 서브클래스를 남겨둡니다. 그런 다음, 서브클래스 컴파일러의 객체를 사용하여 demo() 메서드를 호출하면 어떤 메서드를 호출해야 할지 모르는 모호한 상황에 직면하게 됩니다. 이 문제는 Java에서 다이아몬드 문제로 알려져 있습니다.
이 때문에 Java는 다중 상속을 지원하지 않습니다. 즉, 둘 이상의 다른 클래스를 확장할 수 없습니다. 그래도 하려고 하면 컴파일 타임 오류가 발생합니다.
컴파일 시간 오류
컴파일 시 위의 프로그램은 다음 오류를 생성합니다. -
MultipleInheritanceExample.java:9: error: '{' expected public class MultipleInheritanceExample extends MyInterface1, MyInterface2{ ^ 1 error
해결책
기본 메소드(Java8) 및 인터페이스를 사용하여 Java에서 다중 상속을 달성할 수 있습니다.
Java8부터 기본 메소드 인터페이스에 도입됩니다. 다른 추상 메서드와 달리 이들은 기본 구현이 있는 인터페이스의 메서드입니다. 인터페이스에 기본 메소드가 있는 경우 이미 이 인터페이스를 구현하고 있는 클래스에서 이를 오버라이드(본문 제공)할 필요는 없습니다.
두 개의 다른 인터페이스에서 동일한 기본 메소드(동일한 이름 및 서명)를 가질 수 있으며 클래스에서 이 두 인터페이스를 구현할 수 있습니다.
그렇게 하는 경우 인터페이스 이름과 함께 기본 메서드를 명시적으로 지정하는 클래스의 기본 메서드를 재정의해야 합니다.
예시
interface MyInterface1{ public static int num = 100; public default void display() { System.out.println("display method of MyInterface1"); } } interface MyInterface2{ public static int num = 1000; public default void display() { System.out.println("display method of MyInterface2"); } } public class InterfaceExample implements MyInterface1, MyInterface2{ public void display() { MyInterface1.super.display(); //or, MyInterface2.super.display(); } public static void main(String args[]) { InterfaceExample obj = new InterfaceExample(); obj.display(); } }
출력
display method of MyInterface1 display method of MyInterface2