Как предотвратить наследование для некоторых методов? - PullRequest
8 голосов
/ 22 сентября 2010

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


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

Ответы [ 3 ]

18 голосов
/ 22 сентября 2010

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

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

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

8 голосов
/ 22 сентября 2010

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

1 голос
/ 18 февраля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...