Сокрытие имен при наследовании интерфейсов



 

Когда один интерфейс наследует другой, то в производном интерфейсе может быть объявлен член, скрывающий член с аналогичным именем в базовом интерфейсе. Такое сокрытие имен происходит в том случае, если член в производном интерфейсе объявляется таким же образом, как и в базовом интерфейсе. Но если не указать в объявлении члена производного интерфейса ключевое слово new, то компилятор выдаст соответствующее предупреждающее сообщение.

 

 

Явные реализации

 

При реализации члена интерфейса имеется возможность указать его имя полностью вместе с именем самого интерфейса. В этом случае получается явная реализация члена интерфейса , или просто явная реализация. Так, если объявлен интерфейс IMyIF

 

interface IMyIF {  

int MyMeth(int x) ;

}

 

то следующая его реализация считается вполне допустимой:

 

class MyClass : IMyIF {  

int IMyIF.MyMeth(int x) {

return x / 3;

}

}

 

Как видите, при реализации члена MyMeth() интерфейса IMyIF указывается его полное имя, включающее в себя имя его интерфейса.

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

В приведенном ниже примере программы демонстрируется интерфейс IEven, в котором объявляются два метода: IsEven() и IsOdd(). В первом из них определяется четность числа, а во втором — его нечетность. Интерфейс IEven затем реализуется в классе MyClass. При этом метод IsOdd() реализуется явно.

 

// Реализовать член интерфейса явно,  

using System;

interface IEven {  

bool IsOdd(int x);

bool IsEven(int x);

}

 

class MyClass : IEven {

Явная реализация. Обратите внимание на то, что

Этот член является закрытым по умолчанию,

bool IEven.IsOdd(int x) {

if((x%2) != 0) return true;

else return false;

}

 

Обычная реализация,

public bool IsEven(int x) {

IEven о = this; // Интерфейсная ссылка на вызывающий объект,

return !о.IsOdd(x);

}

}

 

class Demo {

static void Main() {

MyClass ob = new MyClass();

bool result;

 

result = ob.IsEven(4);

if(result) Console.WriteLine("4 — четное число.");

 

// result = ob.IsOdd(4); // Ошибка, член IsOdd интерфейса IEven недоступен

 

Но следующий код написан верно,

//поскольку в нем сначала создается  

// интерфейсная ссылка типа IEven на объект класса MyClass, а затем по  

Этой ссылке вызывается метод IsOdd().

IEven iRef = (IEven) ob;

result = iRef.IsOdd(3);

if(result) Console.WriteLine("3 — нечетное число.");

}

}

 

В приведенном выше примере метод IsOdd() реализуется явно, а значит, он недоступен как открытый член класса MyClass. Напротив, он доступен только по интерфейсной ссылке. Именно поэтому он вызывается посредством переменной о ссылочного типа IEven в реализации метода IsEven().

Ниже приведен пример программы, в которой реализуются два интерфейса, причем в обоих интерфейсах объявляется метод Meth(). Благодаря явной реализации исключается неоднозначность, характерная для подобной ситуации.

 

// Воспользоваться явной реализацией

// для устранения неоднозначности

using System;

 

interface IMyIF_A {

int Meth(int x) ;

}

interface IMyIF_B {

int Meth(int x) ;

}

 

// Оба интерфейса реализуются в классе MyClass.

class MyClass : IMyIF_A, IMyIF_B {

Реализовать оба метода Meth() явно,

int IMyIF_A.Meth(int x) {

return x + x;

}

 

int IMyIF_B.Meth(int x) {

return x * x;

}

 

Вызывать метод Meth() по интерфейсной ссылке.

public int MethA(int x){

IMyIF_A a_ob;  

a_ob = this;

Return a_ob.Meth(x); // вызов интерфейсного метода IMyIF_A

}

 

public int MethB(int x){

IMyIF_B b_ob;

b_ob = this;


Дата добавления: 2019-02-12; просмотров: 269; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!