Java에서 다중 상속이없는 이유는 있지만 여러 인터페이스를 구현할 수 있습니까?


153

Java는 다중 상속을 허용하지 않지만 다중 인터페이스를 구현할 수 있습니다. 왜?


1
질문 제목을보다 설명하기 쉽게 편집했습니다.
Bozho

4
흥미롭게도 JDK 8에는 인터페이스 메소드 구현의 정의를 허용하는 확장 메소드 가 있습니다 . 규칙은 행동의 다중 상속을 관리하기 위해 정의,하지만 좀 더 이해 상태 (의되어 있습니다 문제 .
에드윈 Dalorzo

1
당신은 "자바가 다중 상속을 얻는 방법"만을 말하는 답변에 시간을 낭비하기 전에 ... 나는 당신이 클래스를 올바르게 허용하지 않기 위해 논리적으로 당신에게 내부적으로 일어나야하는 것을주는 @Prabal Srivastava 답변으로 내려가는 것이 좋습니다. 여러 상속을 허용 할 수있는 인터페이스 만 인터페이스에 허용합니다.
Yo Apps

답변:


228

인터페이스 만 지정하기 때문에 어떤 클래스가 아니라하고있다 어떻게 그것을하고있다.

다중 상속의 문제점은 두 클래스가 동일한 작업을 수행하는 다른 방법 을 정의 할 수 있으며 서브 클래스는 선택할 방법을 선택할 수 없다는 것입니다.


8
나는 C ++을 사용했고 똑같은 문제를 꽤 많이 겪었습니다. 나는 최근에 "C ++"방식과 "Java"방식 사이에있는 것처럼 보이는 "특성"을 갖는 스칼라에 대해 읽었습니다.
Niels Basjes

2
이렇게하면 "다이아몬드 문제"를 피할 수 있습니다. en.wikipedia.org/wiki/Diamond_problem#The_diamond_problem
Nick L.

6
Java 8부터는 각 인터페이스마다 하나씩 두 개의 동일한 기본 메소드를 정의 할 수 있습니다. 클래스에서 두 인터페이스를 모두 구현하려면 클래스 자체에서이 메소드를 대체해야합니다. docs.oracle.com/javase/tutorial/java/IandI/…
bobbel

6
이 답변은 정확하지 않습니다. 문제는 Java 8이 입증 할 방법방법을 지정하지 않았습니다 . Java 8에서 두 개의 수퍼 인터페이스 는 구현이 다른 동일한 메소드를 선언 할 수 있지만 인터페이스 메소드가 virtual 이므로 문제가되지 않으므로 이를 덮어 쓰면 문제가 해결됩니다. 실제 문제는 속성의 모호성 에 관한 입니다. 속성을 덮어 쓰는이 모호성을 해결할 수 없기 때문입니다 (속성이 가상이 아님).
Alex Oliveira

1
"속성"은 무엇을 의미합니까?
Bozho

96

내 대학 강사 중 한 명이이 방법을 설명했습니다.

토스터 인 클래스 하나와 NuclearBomb 클래스가 있다고 가정 해 봅시다. 둘 다 "어둠"설정이있을 수 있습니다. 둘 다 on () 메소드를 가지고 있습니다. (하나는 off ()를 가지고 있고 다른 하나는 그렇지 않습니다.) 둘 다의 서브 클래스 인 클래스를 만들려면 여기에서 볼 수 있듯이 이것은 실제로 내 얼굴을 날려 버릴 수있는 문제입니다. .

따라서 주요 문제 중 하나는 부모 클래스가 두 개인 경우 강사의 예에서와 같이 동일한 기능의 다른 구현 또는 동일한 이름을 가진 두 개의 다른 기능을 가질 수 있다는 것입니다. 그런 다음 서브 클래스에서 사용할 클래스를 결정해야합니다. 이를 처리하는 방법은 확실히 있습니다. C ++도 마찬가지입니다. 그러나 Java 설계자들은 이것이 너무 복잡해질 것이라고 생각했습니다.

그러나 인터페이스를 사용하면 다른 클래스의 방법을 빌려주는 대신 클래스가 수행 할 수있는 것을 설명합니다. 다중 인터페이스는 다중 상위 클래스보다 해결해야하는 까다로운 충돌을 유발할 가능성이 훨씬 낮습니다.


5
고마워, NomeN 인용의 출처는 당시 Brendan Burns라는 박사 과정 학생으로, 당시 오픈 소스 Quake 2 소스 저장소의 관리자이기도했습니다. 그림을 이동.
Syntactic

4
이 비유의 문제점은 핵폭탄과 토스터의 서브 클래스를 작성하는 경우 사용시 "핵 토스터"가 합리적으로 폭발 할 수 있다는 것입니다.
101100

20
누군가가 핵폭탄과 토스터를 혼합하기로 결정하면, 폭탄이 터져 얼굴에 터질 자격이 있습니다. 이 인용문은
엉뚱한

1
동일한 프로그래밍 언어는 여러 "인터페이스"상속을 허용하므로이 "정의"는 적용되지 않습니다.
curiousguy

24

"이봐, 그 방법은 유용 해 보인다. 나는 그 클래스도 확장 할 것이다"라고 말할 수 없을 때에도 상속이 과도하게 사용되기 때문이다 .

public class MyGodClass extends AppDomainObject, HttpServlet, MouseAdapter, 
             AbstractTableModel, AbstractListModel, AbstractList, AbstractMap, ...

상속이 과도하다고 말하는 이유를 설명 할 수 있습니까? 신 수업을 만드는 것이 바로 내가하고 싶은 일입니다! 정적 메소드가있는 "도구"클래스를 작성하여 단일 상속을 처리하는 많은 사람들이 있습니다.
Duncan Calvert 1

9
@ DuncanCalvert : 아니오, 코드를 유지 보수 해야하는 경우가 아니라면 그렇게하고 싶지 않습니다. 많은 정적 메소드는 OO의 요점을 놓치지 만 클래스가 개념적으로뿐만 아니라 어디에서 사용되는 코드를 완전히 잃기 때문에 과도한 다중 상속은 훨씬 더 나쁩니다. 둘 다 "필요한 곳에서이 코드를 어떻게 사용할 수 있는가"라는 문제를 해결하려고 노력하고 있지만 이는 간단한 단기 문제입니다. 적절한 OO 디자인으로 해결 된 훨씬 더 어려운 장기 문제는 "프로그램을 예측할 수없는 20 개의 다른 장소에서 중단시키지 않고이 코드를 어떻게 변경합니까?"
Michael Borgwardt

2
@ DuncanCalvert : 높은 응집력과 낮은 결합력을 가진 클래스를 사용하면 해결할 수 있습니다. 즉, 서로 집중적으로 상호 작용하지만 작고 간단한 공개 API를 통해서만 나머지 프로그램과 상호 작용하는 데이터 및 코드 조각이 포함됩니다. 그런 다음 내부 세부 사항 대신 API 측면에서 생각할 수 있습니다. 사람들은 동시에 제한된 양의 세부 사항 만 염두에 둘 수 있기 때문에 중요합니다.
Michael Borgwardt

18

이 질문에 대한 답은 java 컴파일러 (생성자 체인)의 내부 작업에 있습니다. Java 컴파일러의 내부 작업을 보면 :

public class Bank {
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank{
 public void printBankBalance(){
    System.out.println("20k");
  }
}

이 컴파일 후 다음과 같습니다

public class Bank {
  public Bank(){
   super();
  }
  public void printBankBalance(){
    System.out.println("10k");
  }
}
class SBI extends Bank {
 SBI(){
   super();
 }
 public void printBankBalance(){
    System.out.println("20k");
  }
}

클래스를 확장하고 그 객체를 만들면 하나의 생성자 체인이 Object클래스 까지 실행됩니다 .

위의 코드는 정상적으로 실행됩니다. 그러나 Car확장 이라는 다른 클래스 Bank와 하나의 하이브리드 (다중 상속) 클래스 가 있다면 SBICar:

class Car extends Bank {
  Car() {
    super();
  }
  public void run(){
    System.out.println("99Km/h");
  }
}
class SBICar extends Bank, Car {
  SBICar() {
    super(); //NOTE: compile time ambiguity.
  }
  public void run() {
    System.out.println("99Km/h");
  }
  public void printBankBalance(){
    System.out.println("20k");
  }
}

이 경우 (SBICar)는 생성자 체인을 생성하지 못합니다 ( 컴파일 시간 모호성 ).

인터페이스의 경우 객체를 만들 수 없으므로 허용됩니다.

새로운 개념 defaultstatic방법 에 대해서는 인터페이스에서 기본값을 참조하십시오 .

이것이 쿼리를 해결할 수 있기를 바랍니다. 감사.


7

여러 인터페이스를 구현하는 것은 매우 유용하며 언어 구현 자나 프로그래머에게 많은 문제를 일으키지 않습니다. 따라서 허용됩니다. 다중 상속도 유용하지만 사용자에게 심각한 문제를 일으킬 수 있습니다 ( 사망의 다이아몬드 ). 그리고 다중 상속으로 수행하는 대부분의 작업은 구성 또는 내부 클래스를 사용하여 수행 할 수도 있습니다. 따라서 여러 상속은 이익보다 더 많은 문제를 일으키는 것으로 금지됩니다.


"죽음의 다이아몬드"의 문제점은 무엇입니까?
curiousguy

2
@curiousguy 동일한 기본 클래스의 여러 하위 개체, 모호성 (기본 클래스 사용에서 재정의), 이러한 모호성을 해결하는 복잡한 규칙을 포함합니다.
Tadeusz Kopec

@curiousguy : 기본 형식 참조에 대한 개체 참조 캐스팅이 ID 보존이라는 프레임 워크를 제공하는 경우 모든 개체 인스턴스에는 기본 클래스 메서드의 구현이 정확히 하나만 있어야합니다. 만약 ToyotaCarHybridCar모두에서 파생 Car와 오버라이드 Car.Drive한 경우 PriusCar모두 상속 하지만 오버라이드 (override)하지 않은Drive , 시스템은 가상이 무엇인지 식별 방법이 없을 것입니다 Car.Drive해야합니다. 인터페이스는 위의 기울임 꼴 상태를 피하여이 문제를 방지합니다.
supercat

1
@supercat "시스템은 가상 Car.Drive가 무엇을해야하는지 식별 할 방법이 없습니다." <-아니면 컴파일 오류가 발생하여 C ++처럼 명시 적으로 오류를 선택할 수 있습니다.
Chris Middleton

1
@ChrisMiddleton : 방법 void UseCar(Car &foo); 사이 동음 포함 할 것으로 예상 할 수없는 ToyotaCar::DriveHybridCar::Drive(그 다른 유형도 있음을 종종 둘 다 알고 안 이후도 치료를 존재 ). C ++에서와 같이 언어는 코드 ToyotaCar &myCar를 전달하려는 코드 UseCar가 먼저 HybridCar또는로 캐스트해야 ToyotaCar하지만 ((Car) (HybridCar) myCar) .Drive 이후로 캐스트해야 하고 ((Car)(ToyotaCar)myCar).Drive 다른 작업을 수행해야합니다. 신원 보존이 아니었다.
supercat

6

다중 상속에 대한 오라클 문서 페이지에서이 쿼리에 대한 정확한 답변을 찾을 수 있습니다.

  1. 다중 상태 상속 : 여러 클래스에서 필드를 상속하는 기능

    Java 프로그래밍 언어로 인해 둘 이상의 클래스를 확장 할 수없는 한 가지 이유는 여러 클래스에서 필드를 상속 할 수있는 다중 상태 상속 문제를 피하기위한 것입니다.

    다중 상속이 허용되고 해당 클래스를 인스턴스화하여 객체를 만들면 해당 객체는 모든 클래스의 수퍼 클래스에서 필드를 상속합니다. 두 가지 문제가 발생합니다.

    1. 다른 수퍼 클래스의 메소드 또는 생성자가 동일한 필드를 인스턴스화하면 어떻게됩니까?
    2. 어떤 메소드 또는 생성자가 우선합니까?
  2. 다중 구현 상속 : 다중 클래스에서 메소드 정의를 상속하는 기능

    이 접근 방식의 문제점 : 이름 충돌모호성 . 서브 클래스와 수퍼 클래스에 동일한 메소드 이름 (및 서명)이 포함되어 있으면 컴파일러는 호출 할 버전을 판별 할 수 없습니다.

    그러나 Java는 Java 8 릴리스 이후에 도입 된 기본 메소드를 사용 하여 이러한 유형의 다중 상속을 지원합니다 . Java 컴파일러는 특정 클래스가 사용하는 기본 메소드를 판별하기위한 규칙을 제공합니다.

    다이아몬드 문제 해결에 대한 자세한 내용은 아래 SE 게시물을 참조하십시오.

    Java 8에서 추상 클래스와 인터페이스의 차이점은 무엇입니까?

  3. 다중 상속 유형 : 하나 이상의 인터페이스를 구현할 수있는 클래스의 기능.

    인터페이스에 변경 가능한 필드가 포함되어 있지 않으므로 여기에서 다중 상태 상속으로 인해 발생하는 문제에 대해 걱정할 필요가 없습니다.



4

Java는 인터페이스를 통해서만 다중 상속을 지원합니다. 클래스는 여러 인터페이스를 구현할 수 있지만 하나의 클래스 만 확장 할 수 있습니다.

다중 상속은 치명적인 다이아몬드 문제로 이어지기 때문에 지원되지 않습니다. 그러나 해결할 수는 있지만 복잡한 시스템으로 이어 지므로 Java 설립자가 다중 상속을 중단했습니다.

1995 년 2 월 James Gosling의“Java : Overview”백서 ( link )에서는 Java에서 다중 상속이 지원되지 않는 이유에 대한 아이디어를 제공합니다.

고슬링에 따르면 :

"JAVA는 C ++의 거의 사용되지 않고 이해하기 어려운 혼란스러운 기능을 많이 사용하지 않아 경험에 비해 더 많은 슬픔을 겪습니다. 이는 주로 연산자 오버로드 (메소드 오버로드가 있지만), 다중 상속 및 광범위한 자동 강제로 구성됩니다."


링크에 액세스 할 수 없습니다. 친절하게 확인하고 업데이트하십시오.
MashukKhan

3

같은 이유로 C #은 다중 상속을 허용하지 않지만 다중 인터페이스를 구현할 수 있습니다.

다중 상속을 통한 C ++에서 얻은 교훈은 가치보다 더 많은 문제가 발생한다는 것입니다.

인터페이스는 클래스가 구현해야하는 계약입니다. 인터페이스에서 기능을 얻지 못합니다. 상속을 사용하면 부모 클래스의 기능을 상속 할 수 있습니다 (다중 상속으로 인해 혼동 될 수 있음).

다중 인터페이스를 허용하면 어댑터와 같은 디자인 패턴을 사용하여 다중 상속을 사용하여 해결할 수있는 동일한 유형의 문제를 훨씬 더 안정적이고 예측 가능한 방식으로 해결할 수 있습니다.


10
C #에는 Java가 허용하지 않기 때문에 다중 상속이 정확하게 없습니다. Java보다 훨씬 늦게 설계되었습니다. 다중 상속의 주된 문제는 사람들이 그것을 왼쪽과 오른쪽으로 사용하는 방법이었습니다. 대부분의 경우 위임이 훨씬 더 나은 대안이라는 개념은 90 년대 초반과 중반에는 없었습니다. 따라서 자동차가 바퀴와 문이며 앞 유리 인 반면, 자동차에는 바퀴, 문 및 앞 유리가 포함 된 경우 교과서에서 예를 기억합니다. 그래서 자바의 단일 상속은 그 현실에 대한 무자비한 반응이었습니다.
Alexander Pogrebnyak

2
@AlexanderPogrebnyak : 다음 세 가지 중 두 가지를 선택하십시오. (1) 하위 유형 참조에서 수퍼 유형 참조로 ID 보존 캐스트를 허용합니다. (2) 클래스가 파생 클래스를 다시 컴파일하지 않고 가상 공개 멤버를 추가 할 수 있도록합니다. (3) 클래스가 명시 적으로 지정하지 않고 여러 기본 클래스에서 가상 멤버를 암시 적으로 상속 할 수 있도록합니다. 모든 언어가 위의 세 가지를 모두 관리 할 수 ​​있다고 생각하지 않습니다. Java는 # 1과 # 2를 선택했고 C #이 그 뒤를 따랐습니다. C ++은 # 3 만 채택한다고 생각합니다. 개인적으로 # 1과 # 2가 # 3보다 유용하지만 다른 것들은 다를 수 있습니다.
supercat 2016 년

@supercat "언어가 위 세 가지를 모두 관리 할 수 ​​있다고 생각하지 않습니다"– Objective-C의 "비 취약한 ABI에서와 같이 컴파일 타임이 아닌 런타임에 데이터 멤버의 오프셋이 결정되는 경우 ") 또는 클래스 별 기준 (예 : 각 콘크리트 클래스에는 고유 한 멤버 오프셋 테이블이 있음)을 모두 달성하면 3 가지 목표를 모두 달성 할 수 있다고 생각합니다.
상자성 크로와상

@TheParamagneticCroissant : 주요 의미 문제는 # 1입니다. 경우 D1D2에서 모두 상속 B하고, 각 무시하는 기능이 f있는 경우, 그리고 obj유형의 인스턴스 S에서 모두 상속 D1하고 D2있지만이 무시하지 않습니다가 f, 다음에 대한 참조를 캐스팅 S하기 위해 D1뭔가 양보해야 f사용 D1재정의를, 그리고에 캐스팅 B안 그것을 바꾸십시오. 마찬가지로 참조 S를 캐스팅 하면 재정의 D2f사용 하는 것을 생성해야 D2하며 캐스팅을 B변경해서는 안됩니다. 언어가 가상 멤버를 추가 할 필요가없는 경우 ...
supercat

1
@TheParamagneticCroissant : 가능하고 의견에 맞게 선택 목록이 다소 단순화되었지만 런타임을 연기하면 D1, D2 또는 S 작성자가 중단없이 변경 사항을 알 수 없습니다. 학급의 소비자.
supercat

2

이 주제가 가깝지 않기 때문에이 답변을 게시 할 것이므로 java가 다중 상속을 허용하지 않는 이유를 누군가가 이해하는 데 도움이되기를 바랍니다.

다음 클래스를 고려하십시오.

public class Abc{

    public void doSomething(){

    }

}

이 경우 Abc 클래스는 아무것도 확장하지 않습니까? 그렇게 빠르지는 않지만이 클래스는 암시 적으로 모든 것을 작동시키는 기본 클래스 인 Object 클래스를 확장합니다. 모든 것이 대상입니다.

당신이 당신의 IDE는이 같은 방법을 사용할 수 있습니다 것을 볼 수 있습니다 위의 클래스를 사용하려고하면 : equals(Object o), toString(), 등,하지만 당신은 그 방법을 선언하지 않았다, 그들은 기본 클래스에서 온Object

시도해 볼 수 있습니다 :

public class Abc extends String{

    public void doSomething(){

    }

}

이것은 클래스가 암시 적으로 확장 Object되지는 않지만 String말했기 때문에 확장 되기 때문에 좋습니다. 다음 변경 사항을 고려하십시오.

public class Abc{

    public void doSomething(){

    }

    @Override
    public String toString(){
        return "hello";
    }

}

toString ()을 호출하면 클래스는 항상 "hello"를 반환합니다.

이제 다음 수업을 상상해보십시오.

public class Flyer{

    public void makeFly(){

    }

}

public class Bird extends Abc, Flyer{

    public void doAnotherThing(){

    }

}

다시 클래스 Flyer암시 적 확장 메소드를 가진 Object를 확장 toString()합니다. 클래스는 모두 Object간접적으로 확장 되므로이 메소드를 가지므로 toString()from 을 호출 Bird하면 어떤 toString()java를 사용해야합니까? 에서 Abc또는 Flyer? 이것은 두 개 이상의 클래스를 확장하려고 시도하는 클래스에서 발생합니다. 이러한 종류의 "메소드 충돌"을 피하기 위해 인터페이스 개념을 만들었습니다 . 기본적으로 객체를 간접적으로 확장하지 않는 추상 클래스 로 생각할 수 있습니다 . 그것들은 추상적 이기 때문에 객체 인 클래스에 의해 구현되어야 합니다. (인터페이스를 단독으로 설치할 수는 없으며 클래스로 구현해야 함) 모든 것이 계속 잘 작동합니다.

인터페이스와 클래스를 구별하기 위해 키워드 구현 은 인터페이스 전용으로 예약되었습니다.

기본적으로 어떤 것도 확장하지 않기 때문에 같은 클래스에서 원하는 인터페이스를 구현할 수 있습니다 (그러나 다른 인터페이스를 확장하는 인터페이스를 만들 수 있지만 "father"인터페이스는 Object를 확장하지 않습니다). 따라서 인터페이스는 다음과 같습니다. 단지 인터페이스이고 " 메소드 서명 colissions "로 고통받지 않을 것입니다 . 컴파일러가 경고를 보내면 메소드 서명 을 변경하여 수정해야합니다 (서명 = 메소드 이름 + 매개 변수 + 반환 유형) .

public interface Flyer{

    public void makeFly(); // <- method without implementation

}

public class Bird extends Abc implements Flyer{

    public void doAnotherThing(){

    }

    @Override
    public void makeFly(){ // <- implementation of Flyer interface

    }

    // Flyer does not have toString() method or any method from class Object, 
    // no method signature collision will happen here

}

1

인터페이스는 단지 계약이기 때문입니다. 그리고 클래스는 실제로 데이터의 컨테이너입니다.


다중 상속의 근본적인 어려움은 클래스가 자체 재정의 구현을 제공하지 않고 클래스를 다르게 구현하는 다중 경로를 통해 멤버를 상속 할 수 있다는 가능성입니다. 인터페이스 멤버가 구현할 수있는 유일한 장소는 클래스에서 클래스의 하위 클래스가 단일 상속으로 제한되므로 인터페이스 상속은이를 피합니다.
supercat 2016 년

1

예를 들어, 동일한 메소드 m1 ()을 갖는 2 개의 클래스 A, B. 그리고 클래스 C는 A, B를 모두 확장합니다.

 class C extends A, B // for explaining purpose.

이제 클래스 C는 m1의 정의를 검색합니다. 먼저 찾지 못한 경우 수업에서 검색 한 다음 부모님 수업을 확인합니다. 정의를 갖는 A, B 둘 다 여기서 어떤 정의를 선택해야하는지 모호성이 발생합니다. 따라서 Java는 다중 상속을 지원하지 않습니다.


코드를 변경할 수 있도록 두 상위 클래스에 동일한 메소드 또는 변수가 정의되어 있으면 Java 컴파일러에 컴파일러를 제공하는 방법에 대해 설명합니다.
siluveru kiran kumar

1

Java는 다음 두 가지 이유로 다중 상속을 지원하지 않습니다.

  1. 자바에서 모든 클래스는 클래스의 자식입니다 Object. 둘 이상의 수퍼 클래스에서 상속되면 하위 클래스는 Object 클래스의 속성을 가져 오는 모호성을 얻습니다.
  2. 자바에서는 모든 클래스에 생성자가 있습니다. 명시 적으로 작성하거나 전혀 작성하지 않으면. 첫 번째 문장은 super()저녁 식사 클래스 생성자를 호출하기 위해 호출 됩니다. 클래스에 둘 이상의 수퍼 클래스가 있으면 혼동됩니다.

따라서 하나의 클래스가 둘 이상의 수퍼 클래스에서 확장되면 컴파일 시간 오류가 발생합니다.


0

예를 들어 클래스 A에 getSomething 메소드가 있고 클래스 B에 getSomething 메소드가 있고 클래스 C가 A 및 B를 확장하는 경우를 예로 들어 보겠습니다. 누군가 C.getSomething이라고하면 어떻게 될까요? 어떤 메소드를 호출할지 결정할 방법이 없습니다.

인터페이스는 기본적으로 구현 클래스에 포함해야하는 메소드를 지정합니다. 여러 인터페이스를 구현하는 클래스는 클래스가 모든 해당 인터페이스의 메소드를 구현해야 함을 의미합니다. Whci는 위에서 설명한 문제를 일으키지 않습니다.


2
" 누군가 C.getSomething을 호출하면 어떻게됩니까? "이것은 C ++의 오류입니다. 문제 해결됨.
curiousguy

그것이 요점입니다 ... 그것은 분명하다고 생각되는 반대의 예였습니다. 어떤 get 메소드를 호출해야하는지 결정할 방법이 없다고 지적했습니다. 또한 부수적으로, 질문은 java와 관련이 없습니다. c ++가 아닙니다.
John Kane

당신의 요점을 알지 못해 죄송합니다. 분명히 MI의 경우 모호성이 있습니다. 그 반대의 예는 어떻습니까? MI가 모호성을 초래하지 않는다고 누가 주장 했습니까? " 또한 부수적으로, 질문은 자바가 아닌 c ++와 관련이 있습니다. "그래서?
curiousguy

나는 왜 그 모호성이 존재하고 왜 인터페이스가 없는지 보여 주려고 노력했다.
John Kane

예, MI는 모호한 호출을 초래할 수 있습니다. 과부하가 발생할 수 있습니다. Java가 과부하를 제거해야합니까?
curiousguy

0

Test1, Test2 및 Test3이 세 개의 클래스 인 시나리오를 고려하십시오. Test3 클래스는 Test2 및 Test1 클래스를 상속합니다. Test1 클래스와 Test2 클래스가 동일한 메소드를 가지고 있고 하위 클래스 객체에서 호출하는 경우 Test1 또는 Test2 클래스의 메소드를 호출하는 데 모호성이 있지만 인터페이스에 구현과 같은 모호성이 없습니다.


0

Java는 모호성 문제로 인해 다중 상속, 다중 경로 및 하이브리드 상속을 지원하지 않습니다.

 Scenario for multiple inheritance: Let us take class A , class B , class C. class A has alphabet(); method , class B has also alphabet(); method. Now class C extends A, B and we are creating object to the subclass i.e., class C , so  C ob = new C(); Then if you want call those methods ob.alphabet(); which class method takes ? is class A method or class B method ?  So in the JVM level ambiguity problem occurred. Thus Java does not support multiple inheritance.

다중 상속

참조 링크 : https://plus.google.com/u/0/communities/102217496457095083679


0

간단한 방법으로 우리는 하나의 클래스를 상속 (extends) 할 수 있지만 너무 많은 인터페이스를 구현할 수 있습니다. java가 너무 많은 클래스를 확장 할 수 있고 동일한 메소드를 가지고 있다고 가정하십시오.이 시점에서 서브 클래스에서 수퍼 클래스 메소드를 호출하려고하면 어떤 메소드를 실행해야합니까 ??, 컴파일러가 혼란스러워합니다. 예 :-여러 확장을 시도 하지만 이러한 메소드에는 서브 클래스에서 구현해야하는 바디가 없습니다. 여러 개의 구현을 시도 하므로 걱정할 필요 가 없습니다.


1
여기에 예제를 게시 할 수 있습니다. 그렇지 않으면 이것은 9 살짜리 질문에 대한 텍스트 블록처럼 보입니다.
Pochmurnik

-1

* 이것은 Java 초보자이기 때문에 간단한 답변입니다 *

세 가지 클래스가 고려 X, YZ.

우리가 같이 상속하는 그래서 X extends Y, Z 모두 YZ방법 데 alphabet()같은 반환 형식 및 인수를. 이 방법 alphabet()으로는 Y말한다 첫번째 알파벳 표시 및에 방법 알파벳 Z라고 표시 마지막 알파벳 . 에 alphabet()의해 호출 될 때 모호함이 여기에 온다 X. 알파벳 또는 마지막 알파벳 을 표시 할 것인지 여부 따라서 java는 다중 상속을 지원하지 않습니다. 인터페이스의 경우, 고려 YZ인터페이스와 같은. 따라서 둘 다 메소드 선언을 포함 alphabet()하지만 정의 는 포함 하지 않습니다. 첫 알파벳이나 마지막 알파벳을 표시할지 여부를 알려주지 않고 메소드를 선언합니다.alphabet(). 따라서 모호성을 높일 이유가 없습니다. class 내부에서 원하는 것을 사용하여 메소드를 정의 할 수 있습니다 X.

한마디로 인터페이스 정의에서 구현 후 수행되므로 혼란이 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.