2010-08-12 10 views
2

투표를 시작하기 전에 먼저이 질문을 읽으십시오. 여기서 불쾌한 점을 시작하려고하지는 마십시오.다중 상속

이 질문에 대한 유일한 이유는 Java 및/또는 C# 중 하나를 더 많이 알아야하기 때문에 더 많이 고용 될 수 있다는 사실을 점점 더 잘 알고 있습니다. 나는 다중 상속이 J와 C#으로 금지되어 있음을 알 수

: 여기에 좋아

질문입니다. 나는 같은 것을 할 경우 (내가 두 클래스 B와 A로부터 상속하는 클래스를하고 싶은 때문에)하지만 :이 이해

//code in Java 
public class B 
{ 
    public void methodFromB() 
    { 
    } 
} 

public class A extends B 
{ 
    public void methodFromA() 
    { 
    } 
} 

public class C extends A 
{ 
    public void methodFromC() 
    { 
    } 
} 

그래서 사실 지금까지, 나는 그들 모두로부터 상속 않는다 (A와 B 그리고 예, 이것에 대한 형식적인 설명은 객체 A가 전문 B라는 것을 이해합니다. 그러나 내가 원한다면 그다지 적지는 않습니다. 그렇지만 예쁜 것처럼 보이지 않습니다)

대신에 하나의 선언에서 이것을 수행하는 것부터 먼저 다른 클래스로부터 상속받은 클래스 하나를 생성 한 다음 그 클래스에서 파생시켜야합니까?

재미있는 것. 위의 클래스를 NetBeans에서 선언 했으므로 클래스 C의 인스턴스를 만든 후 (main에서)이 클래스에 정의 된 메서드 인 methodFromC를 호출 할 수 없습니다.

그 이유는 무엇입니까?

감사합니다.

+1

"(NetBeans에서) 위와 같은 클래스를 선언하면 클래스 C의 객체를 만든 후 (main에서) methodFromC를 호출 할 수 없습니다"에서 작업하려는 코드의 샘플을 게시 할 수 있습니까? – Bruno

+11

이것은 다중 상속의 예가 아니며, 신이 의미하는대로 일반적인 상속 일뿐입니다. Java voids가 다중 상속을하는 곳은 A와 B를 모두 구현하는 클래스 Ba와 Bb가 있고 그 결과 다이아몬드 모양의 구조가됩니다. Ba와 Bb가 둘 다 public 메서드 m()을 재정의 할 때 Confusion이 설정되어 C가 호출합니다. 호출되고있는 m()의 구현을 절대로 정의하지 않았으므로 예상치 못한 결과가 발생할 수 있습니다. 이 때문에 단일 유형의 구현 만 허용하도록 설계가 선택되었습니다. – mikek

+0

자바와 C#에서 * 금지되어 있다고 말하지는 않겠지 만, 그 언어로 구현되지 않았습니다 (mikek 주를 이유로) – Kris

답변

-1

다중 상속에 대한 정의가 올바르지 않습니다.

OO 수준에서 다중 상속은 명확하고 명확하게 정의됩니다.

그리고 C++과 Java는 다중 상속을 지원합니다.

문제는 대부분의 프로그래머가 OO/OOA/OOD 개념을 전혀 갖고 있지 않으며 OOP 구현 세부 사항 만 알고 있다는 것입니다. 따라서 "상속""구현 상속"과 동의어 인 잘못된 잘못된 믿음.

그러나 이것은 입니다. 완전히 잘못된입니다.

Java는 객체 지향 분석/객체 지향 디자인 수준에 존재하는 실제적이고 유일한 형태의 상속이기 때문에 다중 (인터페이스) 상속을 지원합니다.

은보기 나 하고는 다중 상속을 사용하고 난 자바에 추가 보너스는 "다이아몬드"문제가 존재하지 않는 (다중 인터페이스 상속을 사용하여 Java에서 OOP에 깔끔하게 번역 할 수있는 OOA으로 인한 OOD).

+0

하지만 정확하고 증명할 수있는 정확성으로 내 대답은 SO와 같은 사이트에서 잘 받아 들여지지 않을 것입니다. 이는 구현 세부 사항에 전적으로 초점을 맞추고 더 큰 그림을 전혀 알지 못하는 프로그래머가 자주 방문합니다. 그들은 Java를 배우는 동안 OO를 배우는 중이며, 자바가 단일 상속 만 지원한다는 수많은 잘못된 정보원에 의해 진행되고 있다고 말했습니다. 이런 종류의 사람들이 빛을보고 마음을 바꾸기를 기대하지 마십시오. – NoozNooz42

+0

인터페이스 확장은 다중 상속을 구성하지 않습니다. 구현 세부 사항은 인터페이스에서 파생되지 않으며, 단지 클래스가 포함해야하는 (그리고 구현하는) 스펙입니다. 그러나 다른 의견이 있으시면 언제든지 설명해주십시오. – mikek

+0

@mikek : 물론 여러 인터페이스에서 확장 MI를 구성 (재밌는 sidenote에, 자바가 잘못 : 당신이 쓸 수있는 * 인터페이스 확장 B, C *. 그리고 구체적으로 왜 내 대답은 "다중 인터페이스 상속 "다중 상속"입니다. "코드 재사용"과 "상속"을 심각하게 혼동합니다. 여러 Java 인터페이스에서 확장 할 때 실제로 위임을 사용하여 수행 할 수 있다고 생각되는 사항은 없으므로 MI가 아닙니다. . 다시 한번 : 다중 인터페이스 상속을 사용하여 Java로 쉽게 이식 할 수없는 MI를 사용하는 ** ** ** OOA/OOD를 보여주십시오. – NoozNooz42

7

C의 인스턴스를 만들더라도 C의 메서드가 표시되는지 여부는 사용중인 컴파일 타임 유형에 따라 다릅니다. 예를 들어,

C c = new C(); 
c.methodFromC(); // fine 

는 유효하지만 컴파일 시간 유형이 methodFromC 선언하지 않는, A 때문에

A a = new C(); 
a.methodFromC(); // compiler error 

은 아니다.

C와 A는 모두 B의 하위 클래스이므로 methodFromB을 호출하면 두 경우 모두 문제가되지 않습니다.

+0

하지만 NetBeans에서는 사용할 수 없다는 것을 보여줍니다 (사용할 수 없다는 것을 보여줍니다). c.methodFromC(); 왜? –

+0

c.methodFromC()을 호출 할 수없는 이유에 대한 업데이트가 있습니까? –

+2

지금 게시 한 코드를 사용하면 문제가있는 이유를 알 수 없습니다. 실제로 코드를 컴파일하는 방법을보기 위해 실제로 입력 해 보았습니까? 자동 완성 및 컴파일이 항상 동일한 것은 아닙니다! 그렇지 않으면 액세스 확인자를 다시 확인하고 (모든 항목을 공개) 소문자 c 즉'c.methodOnC() '를 사용하고 있는지 다시 확인하십시오. C.가 대문자이면 작동하지 않습니다. 정적 메서드를 의미하기 때문입니다. – mdma

6

나는 mdma에 동의합니다. 또한 이것이 다중 상속이 아니라는 점에 유의하십시오. 이것은 상속 된 체인입니다. 클래스가 동시에에 두 개 이상의 클래스에서 상속 할 때 다중 상속은 다음과 같습니다 당신이 C#에서 C++

1

대한 대안의 코딩하지 않는 경우 금지 (과에 존재할 수

class A {} 
class B {} 

class C extends A, B {} 

자바,하지만 나는 자바 사람이 아니므로) 인터페이스입니다.

public interface C 
{ 
    int SomeMethodInC(); 
} 

public class A 
{ 
} 

public class B : A, C 
{ 
} 

... in other class.... 
B someB = new B(); 
i someInt = someB.SomeMethodInC(); 

다중 상속과 비슷하지만 그렇지 않습니다. 인터페이스 C는 someMethodInC에 대한 서명을 정의하지만 구현은 정의하지 않습니다. 클래스 B는 someMethodInC를 구현해야합니다.

C#에서는 한 클래스에서만 상속받을 수 있지만 여러 인터페이스를 상속 할 수 있습니다. (자바와 동일합니다.)

C#에서는 확장 메서드를 사용하여 인터페이스에 구현을 연결할 수도 있습니다. SomeExtensionToC의

public static class CExtensions 
{ 
    public static int SomeExtensionToC(this C someC, int someInt) 
    { 
     return someInt * 2; 
    } 
} 
... in code ... 
B objB = new B(); 
y = objB.SomeExtensionToC(x); 

방법 및 실현하는 것이 모두 interface C을 상속하는 모든 클래스에 사용할 수 있습니다. 클래스와 메서드는 모두 정적이며 첫 번째 매개 변수는 C를 구현하는 개체를 참조하여 키워드 "this"를 포함합니다. .NET 프레임 워크의 일부 (LINQ)는 IEnumerable<T>의 확장 메서드로 구현됩니다 .

거의 대부분의 상속과 마찬가지로 나쁜 부분이 없습니다. 확장 메소드는 여전히 인터페이스의 일부로 간주되므로 인터페이스 C에 내재 된 "계약"의 일부로 간주 될 수 있습니다.

+0

확인하려면 예 인터페이스는 매우 유사한 구문과 구현으로 Java에도 존재합니다. http://stackoverflow.com/questions/3355408/explaining-interfaces-to-students/3361740#3361740 동적 언어는 다중 상속을 구현하는 다른 방법을 제공합니다. – JulesLt

2

다중 상속이 아닙니다. 그리고 당신은 맞습니다 C#은 다중 상속을 지원하지 않습니다. C#에서 다중 상속을 시뮬레이션하기위한 정규 패턴이 가치가있는 것은 아래에 있습니다.

public interface IA 
{ 
    void DoA(); 
} 

public interface IB 
{ 
    void DoB(); 
} 

public class A : IA 
{ 
    public void DoA() { Console.WriteLine("A"); } 
} 

public class B : IB 
{ 
    public void DoB() { Console.WriteLine("B"); } 
} 

public class MultipleInheritanceExample : IA, IB 
{ 
    private IA m_A = new A(); 
    private IB m_B = new B(); 

    public void DoA() { m_A.DoA(); } 
    public void DoB() { m_B.DoB(); } 

} 

순수한 다중 상속만큼이나 우아하지는 않지만, 더 많은 작업을 통해 일을 완성합니다. 가장 중요한 다형성 (polymorphism)을 포함하여 다중 상속의 이점 대부분을 얻습니다. 그러나 구현을 상속하지 않습니다. 모든 기본 클래스에서 상속 된 모든 멤버를 다시 구현해야합니다. 이것은 각 구성원 클래스의 구체적인 인스턴스에 해당 구성원 호출을 매핑하여 수행됩니다.

C#에서는 구현 방법을 상속하지 않는 문제를 완화하기 위해 확장 메서드를 사용할 수 있습니다.

public static class IAExtensions 
{ 
    public static void Foo(this IA target) 
    { 
    target.DoA(); 
    } 
} 

물론 이것은 고유 한 문제가 있습니다. 실제로 어떤 종류의 상속도 발생시키지 않으므로 IA 인터페이스에는 실제로 Foo 메서드가 없습니다. 즉, IAExtensions 클래스를 가져 오는 코드 만이 메서드를 사용할 수 있습니다. 즉, 다형성이 없습니다.

이러한 메커니즘을 함께 사용하면 무언가를 함께 사용할 수 있습니다. 대부분의 경우 상속과 유사하지만 기능이 뛰어납니다. 개인적으로 C# 개발자가 순수 다중 상속을 사용하는 것보다 여러 가지 상속을 모방하기 위해 채택한 대안을 발견했습니다. 그러나 C#이 곧 또는 언제든지 여러 번 상속받을 가능성은 거의 없습니다.