Программирование >>  Обработка исключительных ситуаций 

1 ... 63 64 65 [ 66 ] 67 68 69 ... 142


Естественно, что сигнатуры методов в интерфейсе и реализации должны полностью совпадать. Для реализуемых элементов интерфейса в классе следует указывать спецификатор 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.

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



1 ... 63 64 65 [ 66 ] 67 68 69 ... 142

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика