Почему дочерний класс должен реализовывать родительский интерфейс, чтобы скрыть один из этих родительских методов в C #? - PullRequest
4 голосов
/ 11 марта 2011

Я обнаружил такое поведение при работе со сторонней библиотекой, где мне нужно было скрыть и изменить один из ее методов.

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

interface IBaseInterface
{
    string MethodToHide();
}

class BaseClass : IBaseInterface
{
    public string MethodToHide()
    {
        return "BaseClass";
    }
}

class ChildClass : BaseClass
{
    new public string MethodToHide()
    {
        return "ChildClass";
    }
}

Почему, когда я запускаю следующее:

var i = (IBaseInterface) (new ChildClass());
Console.WriteLine(i.MethodToHide());

, вывод равен

BaseClass

, но при изменении подписи ChildClass на

class ChildClass : BaseClass, IBaseInterface

, вывод будет

ChildClass

Почему я должен явно указывать интерфейс для метода BaseClass, который будет скрыт ChildClass?

Ответы [ 3 ]

4 голосов
/ 11 марта 2011

Вам нужно прочитать немного больше о разнице между переопределением и сокрытием :

Ссылка: Переопределить или скрыть

В двух словах:

Скрытие (с использованием нового) запускает метод в соответствии с типом переменной.
Переопределение переопределяет метод и будет использовать только метод ребенка.

Редактировать

Когда вы используете переменную интерфейса:

var i = (IBaseInterface) (new ChildClass());

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

Если ChildClass не явно реализует интерфейс, то компилятор не может связать методы с интерфейсом. С его точки зрения, BaseClass просто имеет методы с тем же именем.

Когда вы явно заявляете, что ChildClass также реализует интерфейс, тогда его методы будут лучшим выбором.

2 голосов
/ 11 марта 2011

Вам необходимо пометить MethodToHide как виртуальный в вашем BaseClass.Тогда ваш ChildClass может переопределить его.См. http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx для получения более подробной информации.

Я считаю, что это релевантная часть спецификации:

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

Поэтому, когда вы приводите исходный объект к IBaseInterface.Он определяет, что типом является BaseClass, поскольку именно он реализует его и вызывает его метод.Во втором примере он разрешает его в ChildClass и вызывает его метод.

1 голос
/ 11 марта 2011

Потому что основной класс реализует интерфейс. Дочерний класс просто определяет новый метод, который не имеет ничего общего с интерфейсом. Фактически, дочерний класс скрывает метод - это то, что делает «новый».

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