2010-09-22 9 views
7

Wie kann ich die Vererbung einiger Methoden oder Eigenschaften in abgeleiteten Klassen verhindern ?!Wie verhindert man Vererbung für einige Methoden?


public class BaseClass : Collection 
{ 
    //Some operations... 
    //Should not let derived classes inherit 'Add' method. 
} 

public class DerivedClass : BaseClass  
{   
    public void DoSomething(int Item)  
    {  
     this.Add(Item); // Error: No such method should exist...  
    }  
} 

Antwort

18

Das gewünschte Muster ist Zusammensetzung ("Has-a"), nicht Vererbung ("Is-a"). BaseClass sollte eine Auflistung enthalten und nicht von der Auflistung erben. BaseClass kann dann selektiv auswählen, welche Methoden oder Eigenschaften an seiner Schnittstelle verfügbar gemacht werden sollen. Die meisten davon sind Passthroughs, die die entsprechenden Methoden für die interne Sammlung aufrufen.

Das Markieren von privaten Dingen in den untergeordneten Klassen funktioniert nicht, da jeder Benutzer mit einer Basistypvariablen (Collection x = new DerivedClass()) weiterhin über den Basistyp auf die "verborgenen" Elemente zugreifen kann.

Wenn "Is-a" vs "Has-a" nicht für Sie klicken, denken Sie daran in Bezug auf Eltern vs Freunde. Du kannst deine Eltern nicht auswählen und sie nicht aus deiner DNA entfernen, aber du kannst wählen, mit wem du dich verbindest.

+5

+1: Liebe die "Eltern vs Freunde" -Metapher:) –

8

Sie können nicht, in diesem Fall Vererbung ist das falsche Werkzeug für den Job. Ihre Klasse muss die Sammlung als privates Mitglied haben, dann können Sie so viel oder so wenig davon freilegen wie Sie möchten.

1

Der Versuch, ein öffentliches Mitglied einer Klasse in einer abgeleiteten Klasse zu verstecken, ist generell eine schlechte Sache (*). Der Versuch, es zu verbergen, um sicherzustellen, dass es nicht aufgerufen wird, ist noch schlimmer und wird im Allgemeinen nicht funktionieren.

Es gibt keine standardisierten idiomatischen Mittel, die ich kenne, um zu verhindern, dass ein geschütztes Mitglied der Elternklasse auf einen untergeordneten Typ zugreift, aber ein neues öffentliches nutzloses Mitglied einer eindeutig nutzlosen Art zu deklarieren wäre ein Ansatz . Das Einfachste wäre eine leere Klasse. Wenn zum Beispiel die Klasse Foo eine leere öffentliche Klasse namens MemberwiseClone deklariert, können Abkömmlinge von Foo MemberwiseClone nicht aufrufen - wahrscheinlich eine gute Sache, wenn MemberwiseClone die Invarianten der Klasse Foo aufbrechen würde.

(*) Die einzige Situation, in der es angebracht ist, wenn eine öffentliche Methode einer abgeleiteten Klasse einen spezialisierteren Typ zurückgibt als die entsprechende Methode in der Basisklasse (zB eine CarFactory.Produce() Methode kann ein Auto zurückgeben, während die FordExplorerFactory.Produce() - Methode einen FordExplorer zurückgeben kann (der von Auto abgeleitet wird). Jemand, der Produce() auf eine CarFactory (aber zufällig eine FordExplorerFactory) aufruft, bekommt ein Auto (was zufällig ein Auto ist) FordExplorer), aber jemand, der Produce() auf dem, was zur Kompilierzeit als FordExplorerFactory bekannt ist, aufruft, erhält ein Ergebnis, das zur Kompilierzeit als FordExplorer bekannt ist.

Verwandte Themen