Как скрыть метод, который является частью реализации интерфейса внутри базового класса, от классов, производных от базового класса?

У меня есть следующая структура:

public class Foo : FooBaseNamespace.FooBase
{
    public Foo()
    {
        Register("abc");
    }
}

public class FooBase : IFoo
{
    public FooBase()
    {

    }

    public void Register(string id)
    {

    }
}

public interface IFoo
{
    void Register(string id);
}

Обратите внимание, что FooBase и IFoo находятся в пространстве имен FooNamespace, а Foo находится в другом пространстве имен, но имеет доступ к FooNameSpace.

Мой вопрос: могу ли я настроить код так, чтобы метод Register(string id) был скрыт от любых классов, производных от FooBase?

Спасибо


person Matt    schedule 09.05.2014    source источник
comment
Закрытые методы   -  person Sayse    schedule 09.05.2014
comment
@Sayse, как, если метод является реализацией интерфейса?   -  person Matt    schedule 09.05.2014
comment
@Sayse Это не меняет того факта, что реализация интерфейса будет public и, следовательно, доступна. Я не думаю, что переопределение является проблемой..   -  person Simon Whitehead    schedule 09.05.2014
comment
связанные: stackoverflow.com/questions/1383434/   -  person    schedule 09.05.2014
comment
Именно поэтому я не опубликовал это как ответ, я не на машине с визуальной студией и не могу это проверить ... просто указываю направление. Я прочитал вопрос, чтобы попытаться остановить унаследованные классы FooBase от переопределения метода   -  person Sayse    schedule 09.05.2014
comment
Голосую за вопрос, потому что сегодня я узнал кое-что новое.   -  person Sinatr    schedule 09.05.2014


Ответы (1)


Я действительно не понимаю, почему вы реализуете IFoo, если хотите скрыть это, и я думаю, что ваше моделирование не совсем правильное.

Дополнительную информацию см. в принципе замещения Лисков.

Заменяемость — это принцип объектно-ориентированного программирования. Он утверждает, что в компьютерной программе, если S является подтипом T, то объекты типа T могут быть заменены объектами типа S (т. е. объекты типа S могут заменять объекты типа T) без изменения каких-либо желаемых условий. свойства этой программы (корректность, выполненная задача и т. д.).

Вы можете содержать реализацию IFoo в своем объекте FooBase (т.е. использовать композицию) и делегировать, например.

public class FooBase {
   private IFoo hiddenFoo;
}

или, возможно, использовать несколько интерфейсов, например. IRegisterable вместе с IFoo, где IRegisterable предоставляет метод Register(), а IFoo предоставляет все остальное. Вы можете выборочно ссылаться на IRegisterable по мере необходимости.

Разделение определений вашего интерфейса на интерфейсы, обеспечивающие отдельные функции, является мощным средством предоставления объектам различной функциональности в зависимости от того, как на них ссылаются (например, один DAO может реализовывать как IReadable, так и IWriteable, и эта функциональность предоставляется отдельно для разных клиентов).

person Brian Agnew    schedule 09.05.2014
comment
Я реализую IFoo для определения контракта для базового класса, но я не хочу распространять такой контракт на классы, производные от базового класса. Я думаю, мой вопрос распространяется на общий случай. Могут ли реализации интерфейса распространяться только на базовый класс, производный от такого интерфейса, но не ниже? - person Matt; 09.05.2014
comment
Я был бы обеспокоен в этом случае, что моделирование является правильным. Я ожидаю, что производные классы могут быть заменены без изменений в клиентском (потребляющем) коде. - person Brian Agnew; 09.05.2014
comment
Я не уверен, что полностью согласен с тем, что мой конкретный вариант использования обязательно указывает на неправильное моделирование. Разве не имеет большого смысла предоставить контракт для базового класса и позволить ему выполнять работу, обещанную контрактом (интерфейс), и позволить классам, производным от базы, не беспокоиться о работе, которую выполняет базовый класс. а лучше заниматься поставленной перед ними задачей? Классы, производные от базы, будут иметь доступ к свойствам, которыми управляют в базе. - person Matt; 09.05.2014
comment
не могли бы вы уточнить, что вы имеете в виду под мощным средством предоставления объектам различных функций в зависимости от того, как на них ссылаются. Как я могу получить базовый класс из двух разных интерфейсов, но предоставлять методы одного интерфейса только классам, производным от базы? Или я что-то не понимаю, и вы просто говорите, что то, чего я пытаюсь добиться, невозможно? - person Matt; 09.05.2014
comment
Я мог бы реализовать класс DaoImpl, реализующий интерфейсы IWriteable и IReadable. Затем я могу предоставить это клиентам (не подклассам) как IReadable или IWriteable. В зависимости от того, как представлен класс (доступен для чтения или записи), клиенту доступны различные возможности, например. мой класс мог бы реализовать записываемую функциональность, но быть представленным некоторым клиентам просто как читаемый - person Brian Agnew; 09.05.2014
comment
Спасибо, Брайан, прочитав Лискова, я лучше понял, что вы пытались сказать. На данный момент я оставляю метод доступным для любых производных классов, пока я буду думать о потенциально другой структуре. - person Matt; 09.05.2014