Г. Шилдт - С#4.0 Полное руководство (1160795), страница 72
Текст из файла (страница 72)
!/ Использовать свойство в интерфейсе. ияглэ Яуяоею; Следующее Следующее Следующее Следующее Следующее Следующее Следующее Следующее Следующее Следующее Глава 12. ИнтерФейсы, структуры и перечисления ЗВЗ четное число равно 2 простое число равно 3 четное число равно 4 простое число равно 5 четное число равно б простое число равно 7 четное число равно 8 простое число равно 11 четное число равно 10 простое число равно 13 384 Часть (. Язык С№ рпЬ11с Тпсеггасе 18еггея ( // Интерфейсное свойство.
1пг нехг ( яес," // возвратить следующее по порядку число яес) // установить следующее число ) ) // Реализовать интерфейс 18еггея, с1аяя ВуТноя : 1Яеггев ( гпг ча1; роЬ1гс ВуТноя() ( ча1 = 0; // Получить или установить значение. роЬ11с 1пг нехг ( чег ( ча1 +" 2; гесогп ча1; ) яес ( ча1 = ча1пе; ) ) ) // Продемонстрировать применение интерфейсного свойства. с1аяя Яег1еяОещоз ( ясас1с чо1о Иагп() ( Вутноя оЬ = пен ВуТноя(); сопяо1е.хг1геь1пе("1пНачать с числа 21"); оЬ.Нехо = 21; Тот(тпо 1=0) г < 5; Тт+) сопяо1е.хг1геьгпе("следующее число равно " + оь.нехг) При выполнении этого кода получается следующий результат.
число равно 2 число равно 4 число равно б число равно 8 число равно 10 Следующее Следующее Следующее Следующее Следующее Начать с числа 21 Следующее число равно 23 Следующее число равно 25 // Получить доступ к последовательному ряду чисел с помощью свойства. Тот (1пс г=О; 1 < 5) 1++) сопяо1е.игзгеьапе("следующее число равно " + оь.нехг)1 Глава 12. ИнтерФейсы, структуры и перечисления 385 Следующее число равно 27 Следующее число равно 29 Следующее число равно 31 Интерфейсные индексаторы В интерфейсе можно также указывать индексаторы. Ниже приведена общая форма объявления интерфейсного индексатора. Интерфейсный индексатор тип элемента Гнтя(1пг индекс)( дег; яес; ) Как и прежде, в объявлении интерфейсных индексаторов, доступных только для чтения или только для записи, должен присутствовать единственный аксессор: дес нли зес соответственно.
Ниже в качестве примера приведен еще один вариант реализации интерфейса 1Яеггез, в котором добавлен индексатор только для чтения, возвращающий йй элемент числового ряда. // добавить индексатор в интерфейс. пагад Яуягею2 рнЬ11с 1псегтасе 1Яег1ея ( // Интерфейсное свойство. 1пс Мехе ( дег; // возвратить следующее по порядку число яег2 // установить следующее число ) Интерфейсный индексатор.
гпг гнья(1пг 1поех) ( дес2 // возвратить указанное в ряду число ) ) // Реализовать интерфейс 1Яеггея. .$ с1аяя Вутноя : 1Яеггея ( 1пг ча1) рпЬ11с Вутиоя () ( ча' = СЧ ) // Получить или установить значение с помощью свойства. рсЬ11с гпс Нехс ( дег ( ча1 += 2; геспгп ча1; ) 386 Часть 1. Язык С() яес ( ча1 = ча1ие; ) // Получить эначение по индексу.
роьззс зпг Сьья(зпя 1пеех) ( Пес ( ча1 = О) гог(1пс 1=0) 1 < 1пг)ех; 1++) ча1 += 2; геспгп ча14 ) ) // Продемонстрировать применение интерфейсного индексатора. с1аяя бег1еяоеюо4 ( ягаг1с чона Мазп() ( ВуТнов оЬ = пен ВуТноя(); // Получить доступ к последовательному ряду чисел с помощью свойства. бог(зпс 1=0; 1 < 5; 1++) Сопяо1е.ИгзгеЬТпе("Следующее число равно " + оЬ.Иехг)) Сопяо1е.иггге51пе("1пНачать с числа 21"); оЬ.Иехг = 21; бог(гпг 1=0) 1 < 5; 1ть) сопяо1е.игзсеььпе("следующее число равно " + оь.иехс)г Сопяо1е.игггеЬ1пе("1пСОросить в 0")) оЬ.Иехг = 0; // Получить доступ к последовательному ряду чисел с помощью индексатора бог(зпс 1=0; 1 < 5) 1+ь) сопяо1е.игьсет ьпе (" следующее число равно " + оЬ [1) ) 1 Вот к какому результату приводит выполнение этого кода.
Начать с числа 21 Следующее число равно 23 Следующее число равно 25 Следующее число равно 27 Следующее число равно 29 Следующее число равно 31 Следующее Следующее Следующее Следующее Следующее число равно 2 число равно 4 число равно б число равно 8 число равно 10 Наследование интерфейсов Один интерфейс может наследовать другой.
синтаксис наследования интерфейсов такой же, как и у классов. Когда в классе реализуется один интерфейс, наследующий другой, в нем должны быть реализованы все члены, определенные в цепочке наследования интерфейсов, как в приведенном ниже примере. Пример наследования интерфейсов.
ивтпс Яувпещ; рпЬ11с тпсегбасе 1А ( чолб мегп1 () г чолб МеСЬ2()г ) // В базовый интерфейс включены методы Метп1() и Мевп2(), а в производный интерфейс добавлен еще один метод — Мегпз() риЬ11с лппегбасе 1В : 1А ( чо1б Мегпз()г ) // В этом классе должны быть реализованы все методы интерфейсов 1А и 1В. с1азз МУС1азз : 1В ( рпЬ11с чо16 Меппг () ( Сопво1е.нгггекьпе("Реализовать метод МеСЬ1().")) ) роЬ11с чо1б Мегп2() ( сопво1е.иглсег сне("Реализовать метод месь2() .")) ) рпЬ11с чолб Мегпз() ( Сопво1е.нглпекьпе (" Реализовать метод МеСЬЗ () . "); ) с1авз 1РЕхпепб ( вгаплс чолб Малп() МуС1авв оЬ = пен МуС1азв () оЬ.Меьпг () г оЬ.Мепп2 О ' ОЬ.МЕГЬЗ(): ) ) сбросить в О Следующее число Следующее число Следующее число Следующее число Следующее число равно 0 равно 2 равно 4 равно б равно 8 Глава 12.
ИнтерФейсы, структуры и перечисления 387 388 Часть (. Язык С№ Ради интереса попробуйте удалить реализацию метода Мес)г1 () из класса МуО1азз. Это приведет к ошибке во время компиляции. Как пояснялось ранее, в любом классе, реализующем интерфейс, должны быть реализованы все методы, определенные в этом интерфейсе, в том числе и те, что наследуются из других интерфейсов. Сокрытие имен при наследовании интерфейсов Когда один интерфейс наследует другой, то в производном интерфейсе может быть объявлен член, скрывающий член с аналогичным именем в базовом интерфейсе.
Такое сокрытие имен происходит в том случае, если член в производном интерфейсе объявляется таким же образом, как и в базовом интерфейсе. Но если не указать в объявлении члена производного интерфейса ключевое слово пен, то компилятор выдаст соответствующее предупреждающее сообщение. Явные реализации При реализации члена интерфейса имеется возможность указать его имя полностью вместе с именем самого интерфейса. В этом случае получается явная реализация члена интерфеиса, или просто явная реализация. Так, если объявлен интерфейс 1му1Г 1пгеггасе 1му1Г ( ьпс мумесн(зпс х) ) то следующая его реализация считается вполне допустимой: с1авз МуС1авв : 1ну1Г ( 1пп 1МугГ.МуМесн(гпс х) гегигп х 1 3; ) ) Как видите, при реализации члена Мумег)з () интерфейса 1му1Г указывается его полное имя, включающее в себя имя его интерфейса.
Для явной реализации интерфейсного метода могут быть две причины. Во-первых, когда интерфейсный метод реализуется с указанием его полного имени, то такой метод оказывается доступным не посредством объектов класса, реализующего данный интерфейс, а по интерфейсной ссылке. Следовательно, явная реализация позволяет реализовать интерфейсный метод таким образом, чтобы он не стал открытым членом класса, предоставляющего его реализацию. И во-вторых, в одном классе могут быть реализованы два интерфейса с методами, объявленными с одинаковыми именами и сигнатурами.
Но неоднозначность в данном случае устраняется благодаря указанию в именах этих методов их соответствующих интерфейсов. Рассмотрим каждую из этих двух возможностей явной реализации на конкретных примерах. В приведенном ниже примере программы демонстрируется интерфейс 1Еиеп, в котором объявляются два метода; 1вЕиеп () и 1зос(с(() . В первом из них определяется четность числа, а во втором — его нечетносгь. Интерфейс 1Еиеп затем реализуется в классе МуО1азз. При этом метод 1зос(б П реализуется явно. Глава 12.
Интерфейсы, структуры и перечисления 389 // Реализовать член интерфейса явно. ця1пд Зуясевг ьппегсасе 1Ечеп ( ЬО01 1яОбб(ьпг х) г Ьоо1 1явчеп(1пг х); ) с1авя МуС1авя : 1Ечеп ( Явная реализация. Обратите внимание на то, что // этот член является закрытым по умолчанию. Ьоо1 1Ечеп.1яобб(ьпг х) ( 11((х$2) != 0) гегцгп сгцег е1яе гегцгп Га1яег ) Обычная реализация. рцЬ11с Ьоо1 1яЕчеп(ьпг х) ( 1Ечеп о = Спьяг // Интерфейсная ссылка на вызывающий объект. гегцгп !о.1яобд(х)г ) ) с1аяя Оево ( ягагьс чогб Магп() ( МуС1аяя оЬ = лен МуС1аяя()г Ьоо1 геяц1С; геяц1С = оЬ.1яЕчеп(4)г 11(геяц1С) Сопяо1е.нг1сеъьпе("4 — четное число."); геяц1Г = оЬ.1яобб(4)г // Ошибка, член 1яобб интерфейса 1Ечеп недоступен Но следующий код написан верно, поскольку в нем сначала создается // интерфейсная ссылка типа 1Ечеп на объект класса МуС1аяя, а затем по // этой ссылке вызывается метод 1яобб().
1Ечеп ьнеГ = (1Ечеп) оЬ; геяц1С = г аес. 1яобд (3) г 11(геяц1С) Сопяо1е.нгьгеъьпе("3 — нечетное число."); ) В приведенном выше примере метод 1 я ос(б () реализуется явно, а значит, он недоступен как открытый член класса МуС1ая я. Напротив, он доступен только по интерфейсной ссылке. Именно поэтому он вызывается посредством переменной о ссылочного типа 1Ечеп в реализации метода 1яЕчеп () . Ниже приведен пример программы, в которой реализуются два интерфейса, причем в обоих интерфейсах объявляется метод Ме СЬ ( ) . Благодаря явной реализации исключается неоднозначностгь характерная для подобной ситуации.