2012-06-01 21 views
11

Czy można uczynić klasę podstawową C# dostępną tylko w zespole biblioteki, do którego została skompilowana, podczas tworzenia innych podklas, które dziedziczą z niej publicznie?C# prywatna (ukryta) klasa podstawowa

Na przykład:

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) 
    { ... } 
} 

Tutaj chciałbym klasa BaseOutput być niedostępne dla klientów mojej bibliotece, ale pozwalają podklasa MyOutput być całkowicie publicznego. Wiem, że C# nie pozwala klasom bazowym mieć bardziej restrykcyjnego dostępu niż podklasy, ale czy istnieje inny legalny sposób osiągnięcia tego samego efektu?

UPDATE

Moje rozwiązanie dla tej konkretnej biblioteki jest, aby klasy bazowej public i abstract i udokumentować ją „Nie używaj tej klasy bazowej bezpośrednio”. Tworzę również konstruktora klasy podstawowej internal, który skutecznie uniemożliwia zewnętrznym klientom korzystanie z klasy lub dziedziczenie tej klasy.

(Szkoda, bo inne języki O-O niech mnie mają ukryte klas bazowych.)

+0

dlaczego nie stworzysz konstruktora 'BaseOutput' tak, aby żaden kod zewnętrzny nie mógł go dziedziczyć? –

+0

@mikez: Tak, właśnie to zrobiłem, zobacz aktualizację powyżej. –

+0

klasa publiczna z wewnętrznym konstruktorem może lepszą opcją (przykład w mojej odpowiedzi) –

Odpowiedz

12
nie

Niestety. Nie możesz wyprowadzić klasy publicznej z klasy wewnętrznej lub prywatnej.

Musisz albo ujawnić klasę podstawową, albo musisz zadeklarować wszystkie metody dla wszystkich podobnych klas. Jeśli wybierzesz trasę, w której ponownie zadeklarujesz wszystkie metody, prawdopodobnie warto utworzyć klasę pomocniczą, która ma ich rzeczywistą implementację. Wciąż jest to trochę podstawowa.

+0

Szkoda. Java pozwala mi to zrobić. –

+1

Dlaczego "niestety"? – stakx

+4

Ponieważ zaoszczędziłoby mi to czasem trochę tablicy. Na przykład przy wdrażaniu tego samego interfejsu w kilku klasach. – CodesInChaos

5

Rozważ wzór, taki jak elewacja. Po to tam są. Nie sądzę, że możesz osiągnąć to, czego potrzebujesz, z czystym dziedzictwem.

+0

Nie chcę tworzyć wielu metod przekazywania. Cały punkt ukrytej klasy bazowej polega na unikaniu replikacji wielu (wspólnych) metod. –

+1

Rzeczywiście, i tak należy faworyzować kompozycję ponad dziedziczenie (http: //en.wikipedia.org/wiki/Composition_over_inheritance) – jeroenh

+0

@jeroenh - Dokładnie przeciwnie do mojego punktu. Chcę, aby klasa bazowa implementowała * większość * metod i zmiennych, i chcę, aby każda pochodna podklasa implementowała * tak mało jak to możliwe *. –

1

zależności od tego co „dużo wspólnych metod” robią można osiągnąć niektóre z nich z wewnętrznych metod rozszerzenie:

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

Innym podejściem jest, aby konstruktor wewnętrzny, aby zapobiec przypadkowemu wyprowadzenie z tej klasy:

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

    ...lots of common methods... 
} 

Uczyni to kod bardziej zrozumiałym w porównaniu do "niezbyt widocznej" klasy pośredniej w hierarchii.