2010-09-22 2 views
7

Как предотвратить наследование некоторых методов или свойств в производных классах?Как предотвратить наследование некоторых методов?


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

ответ

18

Образец, который вы хотите, это композиция («Has-a»), а не наследование («Is-a»). BaseClass должен содержать коллекцию, а не наследовать от коллекции. Затем BaseClass может выборочно выбирать, какие методы или свойства выставлять на свой интерфейс. Большинство из них могут быть просто сквозными, которые вызывают эквивалентные методы во внутренней коллекции.

Маркировка вещей, закрытых в дочерних классах, не будет работать, потому что любой, у кого есть базовая переменная типа (Collection x = new DerivedClass()), по-прежнему сможет получить доступ к «скрытым» членам через базовый тип.

Если «Is-a» vs «Has-a» не нажимает на вас, подумайте об этом с точки зрения родителей и друзей. Вы не можете выбрать своих родителей и не можете удалить их из своей ДНК, но вы можете выбрать, с кем вы связываетесь.

+5

+1: Любите метафору «родители против друзей»:) –

8

Вы не можете, в этом случае наследование является неправильным инструментом для работы. Ваш класс должен иметь коллекцию как частный член, тогда вы можете выставить столько или меньше, сколько хотите.

1

Попытка скрыть публичный элемент класса в производном классе, как правило, является плохим (*). Попытка скрыть его как средство обеспечения его не будет называться еще хуже и вообще не будет работать.

Существует не стандартизованное идиоматическое средство, которое я знаю о том, чтобы предотвратить доступ к защищенному члену родительского класса в суб-производном типе, но объявление нового публичного бесполезного члена явно бесполезного вида будет одним из подходов , Простейшей из таких вещей был бы пустой класс. Например, если класс Foo объявляет пустой публичный класс с именем MemberwiseClone, производные от Foo не смогут вызвать MemberwiseClone - возможно, это хорошо, если MemberwiseClone нарушит инварианты класса Foo.

(*) Единственная ситуация, когда это уместно, - это когда общедоступный метод производного класса возвращает более специализированный тип, чем соответствующий метод в базовом классе (например, метод CarFactory.Produce() может возвращать автомобиль, в то время как метод FordExplorerFactory.Produce() может возвращать FordExplorer (который происходит от автомобиля). Тот, кто называет Produce() тем, что, по их мнению, является CarFactory (но, случается, это FordExplorerFactory), получит автомобиль (который, оказывается, FordExplorer), но тот, кто называет Produce() на том, что известно во время компиляции, чтобы быть FordExplorerFactory, получит результат, который во время компиляции будет известен как FordExplorer.