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

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


В качестве примера рассмотрим интерфейс I Act ion, определяющий базовое поведение персонажей компьютерной игры, встречавшихся в предыдущих главах. Допустим, что любой персонаж должен уметь выводить себя на экран, атаковать и красиво умирать:

interface IAction {

void Draw();

int Attack(int a);

void Die();

int Power { get; }

В интерфейсе IAction заданы заголовки трех методов и шаблон свойства Power, доступного только для чтения. Как легко догадаться, если бы требовалось обеспечить еще и возможность установки свойства, в шаблоне следовало указать ключевое слово set, например:

int Power { get; set; }

В интерфейсе имеет смысл задавать заголовки тех методов и свойств, которые будут по-разному реализованы различными классами разных иерархий.

ВНИМАНИЕ-

Если некий набор действий имеет смысл только для какой-то конкретной иерархии классов, реализующих эти действия разными способами, уместнее задать этот набор в виде виртуальных методов абстрактного базового класса иерархии. То, что работает в пределах иерархии одинаково, предпочтительно полностью определить в базовом классе (примерами таких действий являются свойства Health, Ammo и Name из иерархии персонажей игры). Интерфейсы же чаще используются для задания общих свойств объектов различных иерархий.

Отличия интерфейса от абстрактного класса:

элементы интерфейса по умолчанию имеют спецификатор доступа publ i с и не могут иметь спецификаторов, заданных явным образом;

интерфейс не может содержать полей и обычных методов - все элементы интерфейса должны быть абстрактными;

Интерфейс может наследовать свойства нескольких интерфейсов, в этом случае предки перечисляются через запятую. Тело интерфейса составляют абстрактные методы, шаблоны свойств и индексаторов, а также события.

ПРИМЕЧАНИЕ-

Методом исключения можно догадаться, что интерфейс не может содержать константы, поля, операции, конструкторы, деструкторы, типы и любые статические элементы.



Console.WriteLineC x.GetyO ); Console.WriteLinet Demo.Gets С) ); Console.WriteLinet GetsO );

вызов метода получения поля у вызов метода получения поля s вариант вызова

Как видите, методы класса имеют непосредственный доступ к его закрытым полям. Метод, описанный со спецификатором static, должен обращаться только к статическим полям класса. Обратите внимание на то, что статический метод вызывается через имя класса, а обычный - через имя экземпляра.

ПРИМЕЧАНИЕ-

При вызове метода из другого метода того же класса имя класса/экземпляра можно не указывать.

Параметры методов

Рассмотрим более подробно, каким образом метод обменивается информацией с вызвавшим его кодом. При вызове метода выполняются следующие действия:

1. Вычисляются выражения, стоящие на месте аргументов.

2. Выделяется память под параметры метода в соответствии с их типом.

3. Каждому из параметров сопоставляется соответствующий аргумент (аргументы как бы накладываются на параметры и замещают их).

4. Выполняется тело метода.

5. Если метод возвращает значение, оно передается в точку вызова; если метод имеет тип void, управление передается на оператор, следующий после вызова.

При этом проверяется соответствие типов аргументов и параметров и при необходимости выполняется их преобразование. При несоответствии типов выдается диагностическое сообщение. Листинг 5.3 иллюстрирует этот процесс.

Листинг 5.3. Передача параметров методу

.sing System;

-amespace ConsoleApplicationi class Classl

static int MaxCint a, int b) метод выбора максимального значения {

if ( а > b ) return а; else return b;

static void MainO

in t a = 2, b = 4:

int x = Max( a, b ); Console.WriteLineC x );

вызов метода Max результат: 4



Реализация интерфейса

В списке предков класса сначала указывается его базовый класс, если он есть, а затем через запятую - интерфейсы, которые реализует этот класс. Таким образом, в С# поддерживается одиночное наследование для классов и множественное - для интерфейсов. Это позволяет придать производному классу свойства нескольких базовых интерфейсов, реализуя их по своему усмотрению.

Например, реализация интерфейса IAction в классе Monster может выглядеть следующим образом:

using System:

namespace ConsoleAppl icationl

interface IAction {

void DrawO;

int Attack( int a ):

void DieO:

int Power {get; }

class Monster : IAction

public void DrawO

Console.WriteLineC Здесь б]л + name ):

public int Attack( int ammo )

ammo -= ammo ;

if ( ammo > 0 ) Console.WriteLineC Ба-бах! ); else ammo = 0:

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

класс может иметь в списке предков несколько интерфейсов, при этом он должен определять все их методы.

ПРИМЕЧАНИЕ-

В библиотеке .NET определено большое количество стандартных интерфейсов, которые описывают поведение объектов разных классов. Например, если требуется сравнивать объекты по принципу больше или меньше, соответствующие классы должны реализовать интерфейс IComparable. Мы рассмотрим наиболее употребительные стандартные интерфейсы в последующих разделах этой главы.



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

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