Добавить в цитаты Настройки чтения

Страница 178 из 502

<b>    return x / 3;</b>

<b>  }</b>

<b>}</b>

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

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

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

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

<b>using System;</b>

<b>interface IEven { </b>

<b>  bool IsOdd(int x);</b>

<b>  bool IsEven(int x);</b>

<b>}</b>

<b>class MyClass : IEven {</b>

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

<b>  // этот член является закрытым по умолчанию,</b>

<b>  bool IEven.IsOdd(int x) {</b>

<b>    if((x%2) != 0) return true;</b>

<b>    else return false;</b>

<b>  }</b>

<b>  // Обычная реализация,</b>

<b>  public bool IsEven(int x) {</b>

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

<b>    return !о.IsOdd(x);</b>

<b>  }</b>

<b>}</b>

<b>class Demo {</b>

<b>  static void Main() {</b>

<b>    MyClass ob = new MyClass();</b>

<b>    bool result;</b>

<b>    result = ob.IsEven(4);</b>

<b>    if(result) Console.WriteLine(&quot;4 — четное число.&quot;);</b>

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

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

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

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

<b>    // этой ссылке вызывается метод IsOdd().</b>

<b>    IEven iRef = (IEven) ob;</b>

<b>    result = iRef.IsOdd(3);</b>

<b>    if(result) Console.WriteLine(&quot;3 — нечетное число.&quot;);</b>

<b>  }</b>

<b>}</b>

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

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

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

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

<b>using System;</b>

<b>interface IMyIF_A {</b>

<b>  int Meth(int x) ;</b>

<b>}</b>

<b>interface IMyIF_B {</b>

<b>  int Meth(int x) ;</b>

<b>}</b>

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

<b>class MyClass : IMyIF_A, IMyIF_B {</b>

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

<b>  int IMyIF_A.Meth(int x) {</b>

<b>    return x + x;</b>

<b>  }</b>

<b>  int IMyIF_B.Meth(int x) {</b>

<b>    return x * x;</b>

<b>  }</b>

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