2010-09-22 3 views
7

Comment puis-je empêcher l'héritage de certaines méthodes ou propriétés dans les classes dérivées ?!Comment empêcher l'héritage de certaines méthodes?


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

Répondre

18

Le motif que vous souhaitez est la composition ("Has-a"), pas l'héritage ("Is-a"). BaseClass doit contenir une collection et ne pas hériter de la collection. BaseClass peut ensuite choisir sélectivement quelles méthodes ou propriétés exposer sur son interface. La plupart d'entre eux peuvent simplement être des relais qui appellent les méthodes équivalentes sur la collection interne.

Marquer des éléments privés dans les classes enfants ne fonctionnera pas, car toute personne ayant une variable de type base (Collection x = new DerivedClass()) pourra toujours accéder aux membres "cachés" par le biais du type de base.

Si "Is-a" vs "Has-a" ne clique pas pour vous, pensez-y en termes de parents vs amis. Vous ne pouvez pas choisir vos parents et vous ne pouvez pas les retirer de votre ADN, mais vous pouvez choisir avec qui vous vous associez.

+5

+1: Aime la métaphore "parents vs amis":) –

8

Vous ne pouvez pas, dans ce cas, l'héritage est le mauvais outil pour le travail. Votre classe doit avoir la collection en tant que membre privé, alors vous pouvez en exposer autant ou aussi peu que vous le souhaitez.

1

Essayer de masquer un membre public d'une classe dans une classe dérivée est généralement une mauvaise chose (*). Essayer de le cacher comme un moyen de s'assurer qu'il ne sera pas appelé est encore pire, et généralement ne fonctionnera pas de toute façon.

Il n'existe aucun moyen idiomatique normalisé que je connaisse pour empêcher l'accès à un membre protégé d'une classe parente dans un type sous-dérivé, mais déclarer un nouveau membre public inutile d'un type clairement inutile serait une approche . Le plus simple serait une classe vide. Par exemple, si la classe Foo déclare une classe publique vide appelée MemberwiseClone, les dérivées de Foo ne pourront pas appeler MemberwiseClone - probablement une bonne chose si MemberwiseClone casse les invariants de la classe Foo.

(*) La seule situation où il est approprié est quand une méthode publique d'une classe dérivée renvoie un type plus spécialisé que la méthode correspondante dans la classe de base (par exemple une méthode CarFactory.Produce() peut retourner une voiture, tandis que la méthode FordExplorerFactory.Produce() peut renvoyer un FordExplorer (qui dérive de la voiture) .Quelqu'un qui appelle Produce() sur ce qu'il pense être un CarFactory (mais s'avère être un FordExplorerFactory) obtiendra une voiture (qui se trouve être un FordExplorer), mais quelqu'un qui appelle Produce() sur ce qui est connu au moment de la compilation pour être un FordExplorerFactory obtiendra un résultat qui est connu au moment de la compilation comme un FordExplorer

Questions connexes