Наследование от класса, что это делает? - PullRequest
1 голос
/ 17 сентября 2009

Я видел этот код и у меня есть несколько вопросов:

public class MyClassB : MyClassA, IMyClass
{
     void IMyClass.InsertUser(User user) { }
}

Почему они должны ставить префикс интерфейса IMyClass, а не просто делать:

void InsertUser(User user) { }

или, может быть, сделать

void new InsertUser(User user)

Кроме того, , поскольку вы наследуете от MyClassA (который реализует интерфейс IMyClass), почему мы видим:

public class MyClassB : MyClassA, IMyClass { }

Ответы [ 5 ]

10 голосов
/ 17 сентября 2009

Just

void InsertUser(User user)

не будет работать, так как это объявит приватный метод. Версия с префиксом называется явная реализация интерфейса . Это делает метод доступным только через интерфейс . Одним из его основных применений является возможность реализации нескольких интерфейсов, содержащих один и тот же метод. Лучший пример этого - IEnumerable<T>, который расширяет IEnumerable - оба имеют метод GetEnumerator(), но с разными типами возврата. Вы обычно делаете:

public class Foo : IEnumerable<T>
{
    // Implicit interface implementation
    public IEnumerator<T> GetEnumerator()
    {
        // Real work
    }

    // Explicit interface implementation
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator(); // Calls method above
    }
}

Что касается переопределения интерфейса, это необходимо, если вы также переопределяете интерфейс, который, как вам кажется, вы здесь делаете. Я предполагаю, что MyClassA реализует интерфейс не виртуальным методом (или явно), что означает, что он не может быть переопределен в производном классе ... поэтому, чтобы переопределить интерфейс, вы должны переопределить его.

Лично я бы старался избегать этой ситуации, где это возможно - это может привести к всевозможным проблемам, когда вызываемый метод зависит от того, как именно вы «смотрите» на рассматриваемый объект. Для MyClassA было бы лучше реализовать интерфейс с помощью виртуального метода, который MyClassB мог бы затем переопределить.

1 голос
/ 17 сентября 2009

На ваш первый вопрос уже дан ответ. Вот пример для остальных:

void new InsertUser(User user)

Это создаст новую реализацию InsertUser, которая будет скрывать одну в базовом классе. Итак:

myClassBInstance.InsertUser(user);

вызовет MyClassB.InsertUser (), тогда как

MyClassA myClassAInstance = myClassBInstance;
myClassAInstance.InsertUser(user);

вызовет MyClassA.InsertUser ().

Это отличается от явной реализации интерфейса, которая будет только доступной через интерфейс Тогда

IMyClassA myIClassAInstance = myClassBInstance;
myIClassAInstance.InsertUser(user);

вызовет MyClassB.InsertUser, тогда как:

myClassBInstance.InsertUser(user);

... вызовет MyClassA.InsertUser ().

Теперь, последний вопрос: если MyClassA реализует IMyClass, объявление:

public class MyClassB : MyClassA, IMyClass { }

фактически избыточно (но законно). Как вы предполагаете, MyClassB наследует интерфейс от MyClassA. Итак, декларация

public class MyClassB : MyClassA { }

будет эквивалентно.

0 голосов
/ 17 сентября 2009

Причина, по которой вы должны ввести имя интерфейса или его новое, состоит в том, что MyClassA также использует интерфейс IMyClass, что означает, что он реализует метод InsertCustomer.

0 голосов
/ 17 сентября 2009

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

Есть две причины, по которым ты это сделал. Сначала вы реализуете несколько интерфейсов, которые имеют одинаковое имя метода, но должны вести себя по-разному. Второй - когда вам нужно реализовать интерфейс, но вы не хотите, чтобы методы были общедоступными для пользователя, если они явно не хотят их

0 голосов
/ 17 сентября 2009

Это явная реализация интерфейса .

Скорее всего, так, потому что код позволяет мастеру VS использовать его для него. Это функция, позволяющая устранить неоднозначность методов с другими аналогичными сигнатурами.

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