Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


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




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

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

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

Листинг 12.10

interface IMyIF

{

int MyMeth(int x);

}

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

Листинг 12.11

class MyClass: IMyIF

{

int IMyIF.MyMeth(int x)

{

return x / 3;

}

}

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

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

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

Листинг 12.12

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

 

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 o = this; // Интерфейсная ссылка на вызывающий объект.

 

return!o.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(). Благодаря явной реализации ис­ключается неоднозначность, характерная для подобной ситуации.

Листинг 12.13

// Использовать явную реализацию для устранения неоднозначности.

 

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;

return b_ob.Meth(x); // вызов интерфейсного метода IMyIF_B

}

}

 

class FQIFNames

{

static void Main()

{

MyClass ob = new MyClass();

 

Console.Write("Вызов метода IMyIF_A.Meth(): ");

Console.WriteLine(ob.MethA(3));

 

Console.Write("Вызов метода IMyIF_B.Meth(): ");

Console.WriteLine(ob.MethB(3));

}

}

Вот к какому результату приводит выполнение этой программы.

Вызов метода IMylF A.Meth(): 6

Вызов метода IMyIF_B.Meth(): 9

Анализируя приведенный выше пример программы, обратим прежде всего вни­мание на одинаковую сигнатуру метода Meth () в обоих интерфейсах, IMyIF_A и IMyIF_B. Когда оба этих интерфейса реализуются в классе MyClass, для каждого из них в отдельности это делается явно, т.е. с указанием полного имени метода Meth(). А поскольку явно реализованный метод может вызываться только по интерфейсной ссылке, то в классе MyClass создаются две такие ссылки: одна - для интерфейса IMyIF_А, а другая - для интерфейса IMyIF_В. Именно по этим ссылкам происходит обращение к объектам данного класса с целью вызвать методы соответствующих интерфейсов, благодаря чему и устраняется неоднозначность.





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


Дата добавления: 2016-12-28; Мы поможем в написании ваших работ!; просмотров: 519 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Лучшая месть – огромный успех. © Фрэнк Синатра
==> читать все изречения...

2257 - | 2143 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.009 с.