2012-06-01 4 views
11

C# 기본 클래스는 컴파일 된 라이브러리 어셈블리 내에서만 액세스 할 수 있지만 공용 클래스를 상속하는 다른 하위 클래스는 공용으로 만들 수 있습니까? 예를 들어C# private (hidden) 기본 클래스

는 :

여기
using System.IO; 

class BaseOutput: Stream   // Hidden base class 
{ 
    protected BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

public class MyOutput: BaseOutput // Public subclass 
{ 
    public BaseOutput(Stream o): 
     base(o) 
    { ... } 

    public override int Write(int b) 
    { ... } 
} 

나는 BaseOutput 클래스 내 라이브러리의 클라이언트에 액세스 할 수 좋아하지만, 서브 클래스 MyOutput이 완전히 공개 할 수 있도록 것입니다. 나는 C#이 기본 클래스가 하위 클래스보다 더 제한적인 액세스를 허용하지 않는다는 것을 알고 있지만 동일한 효과를 얻기위한 다른 합법적 인 방법이 있습니까?

UPDATE이 특정 라이브러리에 대한

내 솔루션은 기본 클래스 publicabstract을하고, 그것을 문서화하는 "직접이 기본 클래스를 사용하지 마십시오"입니다. 또한 기본 클래스 internal의 생성자를 만들어 외부 클라이언트가 클래스를 사용하거나 상속하는 것을 효과적으로 방지합니다.

(다른 O-O의 언어 나 기본 클래스를 숨긴 할 수 있기 때문에이 수치이다.) 불행하게도

+0

'BaseOutput'의 생성자를 내부 코드로 만들어 외부 코드가 상속받을 수없는 이유는 무엇입니까? –

+0

@mikez : 예, 그랬습니다. 위의 업데이트를 참조하십시오. –

+0

내부 생성자가있는 공용 클래스가 더 좋은 옵션 일 수 있습니다 (내 대답은 샘플) –

답변

12

없습니다. 내부 클래스 또는 비공개 클래스에서 공용 클래스를 파생시킬 수 없습니다.

기본 클래스를 노출해야하거나 모든 유사한 클래스에 대해 모든 메서드를 선언해야합니다. 모든 메소드를 다시 선언하는 경로를 간다면 실제로 구현 된 도우미 클래스를 만드는 것이 유용 할 것입니다. 아직도 꽤 많은 상용구입니다.

+0

너무 좋지 않습니다. Java는 이것을 가능하게합니다. –

+1

왜 "불행히도"? – stakx

+4

가끔 보편적으로 꽤 많은 보충 판을 구해 냈을 것이기 때문입니다. 예를 들어 여러 클래스에서 동일한 인터페이스를 구현할 때. – CodesInChaos

5

Facade와 같은 패턴을 고려하십시오. 그게 그들이 그곳에있는 이유입니다. 나는 당신이 직선 상속으로 당신이 요구하는 것을 성취 할 수 있다고 생각하지 않습니다. 무엇을 "일반적인 방법의 많은"에 따라

+0

포워딩 방법을 많이 만들 필요가 없습니다. 숨겨진 기본 클래스 뒤에있는 요점은 많은 (일반적인) 메서드를 복제하지 않는 것입니다. –

+1

사실, 어쨌든 상속에 비해 구성을 선호해야합니다 (http : //en.wikipedia.org/wiki/Composition_over_inheritance) – jeroenh

+0

@jeroenh - 그건 내 포인트의 정반대입니다. 기본 클래스에서 메서드 및 변수의 * 대부분 *을 구현하기를 원하며, 각 파생 된 하위 클래스에서 * 가능한 한 * 구현하기를 원합니다. –

1

는 내부 확장 방법과 그것의 일부를 얻을 수하고 있습니다 :

internal static class MyStreamExtensions 
{ 
    internal static int UsefulOne(this Stream stream) 
    { 
    return 42; 
    } 
} 

또 다른 방법은 그 클래스에서 의도하지 않은 파생을 방지하기 위해 생성자 내부 만드는 것입니다 :

public class BaseOutput: Stream 
{ 
    internal BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

이렇게하면 코드가 "실제로 보이지 않는"중간 계층의 계층에 비해 더 이해할 수있게됩니다.

관련 문제