|
Программирование >> Обработка исключительных ситуаций
Естественно, что сигнатуры методов в интерфейсе и реализации должны полностью совпадать. Для реализуемых элементов интерфейса в классе следует указывать спецификатор publ ic. К этим элементам можно обращаться как через объект класса, так и через объект типа соответствующего интерфейса1: Monster Vasia = new MonsterC 50. 50, Вася ); объект класса Monster Vasia.DrawC): результат: Здесь был Вася lArtion Actor = new MonsterC 10, 10, Маша ); объект типа интерфейса Actor.DrawC); результат: Здесь был Маша Удобство второго способа проявляется при присваивании объектам типа I Action ссылок на объекты различных классов, поддерживающих этот интерфейс. Например, легко себе представить метод с параметром типа интерфейса. На место этого параметра можно передавать любой объект, реализующий интерфейс: static void Act С lAction A ) { A.DrawC); static void Maine) Monster Vasia = new MonsterC 50, 50, Вася ); ActC Vasia ); Этот объект должен содержать ссылку на класс, поддерживающий интерфейс. Естественно, что объекты типа интерфейса, так же как и объекты абстрактных классов, создавать нельзя. public void OieO Console.WriteLineC Monster + name + RIP ); health = 0: public int Power ciet return ammo * health; Существует второй способ реализации интерфейса в классе: явное указание имени интерфейса перед реализуемым элементом. Спецификаторы доступа при этом не указываются. К таким элементам можно обращаться в программе только через объект типа интерфейса, например: class Monster lAction int IAction.Power return ammo health; void IAction.DrawO Console.WriteLineC Здесь был + name ); IAction Actor = new Monster( 10, 10, Mama ); Actor.Draw(); обращение через объект типа интерфейса Monster Vasia = new MonsterC 50, 50, Вася ); Vasia.DrawO; ошибка! Таким образом, при явном задании имени реализуемого интерфейса соответствующий метод не входит в интерфейс класса. Это позволяет упростить его в том случае, если какие-то элементы интерфейса не требуются конечному пользователю класса. Кроме того, явное задание имени реализуемого интерфейса перед именем метода позволяет избежать конфликтов при множественном наследовании, если элементы с одинаковыми именами или сигнатурой встречаются более чем в одном интерфейсе1. Пусть, например, класс Monster поддерживает два интерфейса: один для управления объектами, а другой для тестирования: interface ITest void DrawO; interface IAction Методы с одинаковыми именами, но с различными сигнатурами к конфликту не приводят, они просто считаются перегруженными. void Draw(); int Attack( int a ); void Die(); int Power { get; } lass Monster : IAction, ITest void ITest.DrawO { Console.Writeline( Testing + name ); void IAction.DrawO Console.WriteLineC Здесь был + name ); Оба интерфейса содержат метод Draw с одной и той же сигнатурой. Различать их помогает явное указание имени интерфейса. Обращаться к этим методам можно, используя операцию приведения типа, например: Monster Vasia = new MonsterC 50, 50, Вася ); :(ITest)Vasia).DrawO; результат: Здесь был Вася ;(IAction)Vasia).DrawO; результат: Testing Вася Впрочем, если от таких методов не требуется разное поведение, можно реализовать метод первым способом (со спецификатором public), компилятор не возражает: slass Monster : lAction. ITest public void DrawO Console.WriteLineC Здесь был + name ): К методу Draw, описанному таким образом, можно обращаться любым способом: через объект класса Monster, через интерфейс lAction или ITest. Конфликт возникает в том случае, если компилятор не может определить из контекста обращения к элементу, элемент какого именно из реализуемых интерфейсов требуется вызвать. При этом всегда помогает явное задание имени интерфейса.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |