Программирование >>  Программирование с использованием ajax 

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


Данная строка кода приведет к вызову реализации метода EatFood (), содержащейся в производном классе. Важно обратить внимание на то, что вызывать подобным образом методы, определенные в производном классе, нельзя. То есть следующий код работать не будет:

myAnimal.Moo();

Однако приводить переменную типа базового класса в переменную типа производного класса и вызывать метод производного класса показанным ниже образом можно:

Cow myNewCow = (Cow)myAnimal; myNewCow.Moo();

Эта операция приведения будет приводить к выдаче исключения в случае, если тип исходной переменной не будет совпадать ни с типом Cow, ни с типом производного от него класса. Для определения типа объекта существуют свои приемы, о которых речь пойдет в следующей главе.

Полиморфизм является чрезвычайно полезной технологией для решения задач с использованием минимального количества кода в разных объектах, происходящих от одного единственного класса. Следует отметить, что полиморфизм может применяться не только в отношении классов, имеющих одинаковый родительский класс. Он точно так же может применяться и, скажем, в отношении дочерних и внучатых классов, главное, чтобы в их иерархии наследования присутствовал какой-то общий класс.

Напоследок важно обратить внимание и запомнить, что в С# все классы наследуются от базового класса object, который является корневым в их иерархиях наследования. Благодаря этому все объекты могут считаться экземплярами класса object. Именно это и позволяет методу Console .WriteLine () обрабатывать практически бесконечное количество комбинаций параметров при построении строк. Каждый параметр после первого воспринимается как экземпляр object, что позволяет выводить выходные данные любого объекта на экран. Для этого вызывается метод ToString () (являющийся членом класса object). Этот метод можно переопределять и предоставлять для него более подходящую реализацию, а можно и просто воспользоваться реализацией, предлагаемой по умолчанию, в которой он возвращает имя класса (квалифицированное пространствами имен, в которых он присутствует).

Полиморфизм интерфейсов

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

Например, предположим, что вместо базового класса Animal метод EatFood () помещается в интерфейс по имени IConsume. Этот интерфейс могут поддерживать оба класса - Cow и Chicken, - но только в таком случае каждый из них должен обязательно иметь свою реализацию метода EatFood () (поскольку интерфейсы не содержат реализаций). После этого к этому методу станет можно получать доступ с помощью примерно такого кода:

Cow myCow = new Cow () ; Chicken myChicken = new Chicken (); IConsume consijmelnterface ; consvimelnterface = myCow; consvimelnterface. EatFood () ; consvimelnterface = myChicken; consumelnterface.EatFood();



Такой подход предоставляет простой способ для вызова множества объектов одинаковым образом и избавляет от зависимости от общего базового класса. В этом коде вызов consumelnterf асе. EatFood () будет приводить к вызову метода EatFood () либо класса Cow, либо класса Chicken, в зависимости от того, какой экземпляр будет присвоен переменной типа интерфейса.

Здесь важно обратить внимание на то, что производные классы наследуют интерфейсы, поддерживаемые их базовыми классами. В предыдущем примере интерфейс IConsume может поддерживаться как классом Animal, так и обоими классами Cow и Chicken. Запомните, что классы с общим базовым классом вовсе необязательно имеют общие интерфейсы и наоборот.

Отношения между объектами

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

В настоящем разделе дается краткий обзор следующих отношений.

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

□ Коллекции. Один класс выступает в роли контейнера для нескольких экземпляров другого класса. Эти отношения напоминают те, что образуются при создании массивов объектов, но предусматривают дополнительные функциональные возможности, наподобие индексации, поиска, изменения размера и т.д.

Включение

Отношение включения легко достигается использованием для хранения экземпляра объекта поля-члена. Это поле может быть общедоступным, в случае чего пользователи объекта-контейнера будут иметь доступ к предоставляемым им методам и свойствам во многом подобно тому, как это происходит при наследовании. Однако доступа к внутренним деталям класса через производный класс, который возможен в случае наследования, в таком случае не будет.

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

Например, класс Cow мог бы содержать класс Udder (Вымя) с общедоступным методом Milk () (Доить). Объект Cow мог бы вызывать этот метод по мере необходимости, например, в виде части своего метода SupplyMilk (), но пользователям объекта Cow () такие детали при этом были бы не видны (или не важны).

Содержащиеся внутри других классы в UML могут изображаться с помощью ассоциативных линий. В простом случае концы этих линий обозначаются единицей (1), указывая тем самым на то, что речь идет об отношениях типа один к одному (т.е., например, что один экземпляр Cow будет содержать один экземпляр Udder).



Для ясности экземпляр класса Udder может также быть изображен в виде приватного поля класса Cow, как показано на рис. 8.10.

udder

rmiiko

-containedUdder: Udder

+ Moo() -hSupplyMiIkO

Puc. 8.10. Представление отноиьения включения в UML

Коллекции

в главе 5 говорилось о том, что для хранения нескольких переменных одинакового типа можно использовать массивы. То же самое можно делать и для объектов (напоминаем, что типы переменных, которые приводились в этой книге, на самом деле тоже являлись объектами, так что ничего особо удивительного в этом быть не должно). Ниже приведен пример:

Animal[] animals = new Animal[5];

Коллекция представляет собой, по сути, массив, но с дополнительными возможностями. Коллекции реализуются в виде классов во многом точно так же, как и другие объекты. Их имена часто совпадают с именами объектов, которые они хранят, но только во множественном числе: например, класс с именем Animals может содержать коллекцию объектов Animal.

Главное отличие от массивов состоит в том, что коллекции обычно реализуют дополнительные функции, вроде методов Add () и Remove () для добавления и удаления элементов из коллекции. У них также обычно имеется свойство Item, которое возвращает объект по его индексу. Довольно часто это свойство реализуется так, чтобы оно предусматривало более сложный доступ. Например, класс Animals мог бы быть спроектирован так, чтобы к каждому конкретному объекту Animal доступ можно было получать по его имени. В UML подобные отношения изображаются так, как показано на рис. 8.11.

0..*

animal

animals

Рис. 8.11. Представление отношения коллекции в UML



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

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