2010-01-19 10 views
8

Rozważmy pracownika, Manager, a zajęcia Asystent:.NET Dziedziczenie: stłumić właściwość z klasy bazowej

public class Emp 
{ 
    public string Name { get; set; } 
    public Manager Manager { get; set; } 
    public Assistant Assistant { get; set; } 
} 

public class Manager : Emp 
{ 
} 

public class Assistant : Emp 
{ 
} 

Celem jest, aby nie pozwolić na kawałek kodu, aby uzyskać dostęp do właściwości tak:

var foo = new Manager(); 
var elmo = new Emp(); 
elmo.Manager = foo; 
elmo.Manager.Manager = new Manager(); 
//how to disallow access to Manager.Manager ? 

Ponieważ Manager dziedziczy po Emp, ma właściwość .Manager i .Assistant.

Pytanie

Czy istnieją jakieś modyfikatory w realizacji spadków .NET do zlikwidowania .Manager i .Assistant właściwości?

Aktualizacja

Dziękujemy za wielkie odpowiedzi, każdego. Miałem nadzieję, że uproszczenie i pomysł Emp/Mgr przejdzie przez to pytanie. Oczywiste jest, że dziedziczenie w tym przykładzie powinno zostać przeniesione do innej wspólnoty (coś w rodzaju Person, gdzie klasy będą się dzielić imionami, datami urodzenia itp.) Twój wkład jest bardzo cenny!

+0

Pachnie jak kwestia projektowania dla mnie. Podczas gdy Menedżerowie mogą zgłaszać się do innego menedżera, Asystenci prawdopodobnie nie mają asystenta. Być może podstawą powinna być osoba ... – Walter

Odpowiedz

9

Spowoduje to naruszałoby Liskov substitution principle i jest zwykle oznaką wątpliwej konstrukcji. Zasadniczo każda podklasa powinna móc być używana w dowolnym kontekście, w którym znajduje się klasa podstawowa. Jeśli Manager s nie mają .Manager s, nie są one Emp s, i nie powinny z nich dziedziczyć.

2

Nie, nie ma.

Można wykonać właściwość klasy podstawowej virtual, a następnie przesłonić ją, aby rzucić wyjątek w ustawiacz, ale nie ma możliwości podania błędu podczas kompilacji. Po tym wszystkim, nie ma nic zrobić w czasie kompilacji, aby zapobiec

(elmo.Manager as Employee).Manager = new Manager(); 

Można jednak napisać

public class ManagerEmployee : Emp {  
    public new ManagerEmployee Manager { 
     get { return base.Manager; } 
    } 
} 

Zauważ, że to nie przeszkodzi odlew.

5

Nie - ponieważ złamie się Liskov's Subsitution Principle. Zasadniczo możesz dodawać rzeczy, ale nie możesz ich zabrać.

Można potencjalnie przesłonić właściwość, aby wyrzucić wyjątek w czasie wykonywania, ale nie można tego zrobić podczas kompilacji.

Generalnie, jeśli chcesz zabronić tego typu rzeczy, należy wziąć pod uwagę skład zamiast dziedziczenie, jak nie ma prawdziwej relacji dziedziczenia.

0

Jak powiedzieli inni. Nie. Dodam, że jeśli nie każdy pracownik ma menedżera i asystenta, to hierarchia dziedziczenia jest błędna. Wydawać by się mogło, że jedyną rzeczą, jaką ma udział pracownika i menedżera, jest imię. Możesz dodać dziedziczenie, ale nie możesz zabrać go przez dziedziczenie.

0

Nie, nie mogę tego zrobić, a ty nie chcesz - albo menedżera jest pracownikiem i ma Menedżer i asystent, albo nie, a zatem nie powinny mieć inną klasę bazową czyli sytuacja ta wskazuje, wada projektowa.Jedną z możliwości może być zwrócenie wartości null dla tych właściwości, jeśli ma to sens dla domeny.

1

Podobnie jak większość rzeczy, to zależy. Biorąc pod uwagę następujących klas:

public class foo 
{ 
    public string Test { get { return "foo"; } } 
} 

public class bar : foo 
{ 
    public new string Test { get { return "bar"; } } 
} 

i następujący kod:

 bar a = new bar(); 
     // returns bar 
     literalTest1.Text = a.Test; 

     foo b = new foo(); 
     // returns "foo" 
     literalTest2.Text = b.Test; 

     foo c = new bar(); 
     // returns "foo" 
     literalTest3.Text = c.Test; 

Można zobaczyć, na podstawie powyższych uwag, które może zastąpić właściwość, która nie jest zadeklarowany jako wirtualny. Jednak przesłonięta właściwość będzie używana tylko wtedy, gdy zmienna obiektowa zostanie zadeklarowana jako typ, który przesłania właściwość - nie jako żaden z jej przodków. To skutecznie niszczy polimorfizm.

Napraw zamiast tego klasę przodków.

Powiązane problemy