
- •Оглавление
- •Об авторе
- •Посвящение
- •Благодарности
- •Ждем ваших отзывов!
- •Что такое .NET
- •Создание исходной программы
- •Тестовая поездка
- •Каркас программы
- •Комментарии
- •Введение в хитрости панели элементов
- •Повторное использование кода из панели элементов
- •Правила объявления переменных
- •Вариации на тему int
- •Объявление переменной с плавающей точкой
- •Ограничения переменных с плавающей точкой
- •Объявление переменных типа decimal
- •Сравнение десятичных и целых чисел, а также чисел с плавающей точкой
- •Логичен ли логический тип
- •Символьные типы
- •Что такое тип-значение
- •Неизменяемость строк
- •Основные операции над строками
- •Сравнение строк
- •Сравнение без учета регистра
- •Отличие строк в разных регистрах
- •Преобразование символов строки в символы верхнего или нижнего регистра
- •Поиск в строках
- •Как искать
- •Пуста ли строка
- •Удаление пробельных символов
- •Анализ числового ввода
- •Обработка последовательности чисел
- •Объединение массива строк в одну строку
- •Арифметика
- •Простейшие операторы
- •Порядок выполнения операторов
- •Оператор инкремента
- •Сравнение чисел с плавающей точкой
- •Составные логические операторы
- •Вычисление типа операции
- •Типы при присваивании
- •Перегрузка операторов
- •Ветвление с использованием if и switch
- •Инструкция if
- •Инструкция else
- •Как избежать else
- •Вложенные инструкции if
- •Конструкция switch
- •Циклы
- •Цикл без счетчика
- •Правила области видимости
- •Пример
- •Зачем нужны разные циклы
- •Зачем нужны массивы
- •Массив фиксированного размера
- •Массив переменного размера
- •Свойство Length
- •Инициализация массивов
- •Понятие <т>
- •Обобщенные коллекции
- •Инстанцирование пустого списка
- •Создание списка целых чисел
- •Преобразования списков в массивы и обратно
- •Подсчет количества элементов в списке
- •Поиск в списках
- •Инициализаторы массивов и коллекций
- •Выполнение специфичных для множеств задач
- •Создание множества
- •Добавление элемента в множество
- •Выполнение объединения
- •Пересечение множеств
- •Получение разности
- •Не используйте старые коллекции
- •Обход каталога файлов
- •Начало программы
- •Получение начальных входных данных
- •Создание списка файлов
- •Форматирование вывода
- •Вывод в шестнадцатеричном формате
- •Обход коллекций: итераторы
- •Доступ к коллекции: общая задача
- •Использование foreach
- •Формат индексатора
- •Блок итератора
- •Создание каркаса блока итератора
- •Итерирование дней в месяцах
- •Что же такое коллекция
- •Синтаксис итератора
- •Блоки итераторов произвольного вида и размера
- •Обобщенные классы безопасны
- •Обобщенные классы эффективны
- •Очередь с приоритетами
- •Распаковка пакета
- •Написание обобщенного кода
- •Использование простого необобщенного класса фабрики
- •Незавершенные дела
- •Ковариантность
- •Использование механизма исключений для сообщения об ошибках
- •Что происходит при генерации исключения
- •Исключительный пример
- •Что делает этот пример "исключительным"
- •Трассировка стека
- •Советы по написанию кода с хорошей обработкой ошибок
- •Анализ возможных исключений метода
- •Как выяснить, какие исключения генерируются теми или иными методами
- •Генерирующие исключения выражения
- •Работа с перечислениями
- •Создание перечислений с инициализаторами
- •Указание типа данных перечисления
- •Применение перечислений в конструкции switch
- •Процедурные поездки
- •Объектно-ориентированные поездки
- •Определение класса и объекта
- •Определение класса
- •Что такое объект
- •Различие между объектами
- •Работа со ссылками
- •Классы, содержащие классы
- •Определение константных членов-данных и членов-данных только для чтения
- •Передача аргументов методу
- •Передача методу нескольких аргументов
- •Соответствие определений аргументов их использованию
- •Перегрузка методов
- •Реализация аргументов по умолчанию
- •Возврат значения оператором return
- •Кортеж с двумя элементами
- •Создание кортежей более чем с двумя элементами
- •Глава 14 Поговорим об этом
- •Определение методов
- •Определение статического метода
- •Определение метода экземпляра
- •Полное имя метода
- •Ключевое слово this
- •Когда this используется явно
- •Что делать при отсутствии this
- •Использование локальных функций
- •Прочие уровни безопасности
- •Методы доступа
- •Пример управления доступом
- •Выводы
- •Статические свойства
- •Побочные действия свойств
- •Дайте компилятору написать свойства для вас
- •Методы и уровни доступа
- •Замена конструктора по умолчанию
- •Конструирование объектов
- •Непосредственная инициализация объекта
- •Конструирование с инициализаторами
- •Инициализация объекта без конструктора
- •Определение свойств с кодом
- •Определение конструкторов и деструкторов с кодом
- •Определение методов доступа к свойствам с кодом
- •Определение методов доступа к событиям с кодом
- •Наследование класса
- •Более сложный пример наследования
- •ЯВЛЯЕТСЯ или СОДЕРЖИТ
- •Доступ к BankAccount через содержание
- •Отношение СОДЕРЖИТ
- •Заменяемость классов
- •Неверное преобразование времени выполнения
- •Указание конкретного конструктора базового класса
- •Обновленный класс BankAccount
- •Перегрузка унаследованного метода
- •Простейший случай перегрузки метода
- •Различные классы, различные методы
- •Сокрытие метода базового класса
- •Вызов методов базового класса
- •Что неверно в стратегии использования объявленного типа
- •Использование is для полиморфного доступа к скрытому методу
- •Объявление метода виртуальным и перекрытие
- •Получение максимальной выгоды от полиморфизма
- •Разложение классов
- •Абстрактный класс: ничего, кроме идеи
- •Как использовать абстрактные классы
- •Создание абстрактных объектов невозможно
- •Опечатывание класса
- •Реализация интерфейса
- •Именование интерфейсов
- •Наследование и реализация интерфейса
- •Преимущества интерфейсов
- •Тип, возвращаемый методом
- •Что скрыто за интерфейсом
- •Гибкие зависимости через интерфейсы
- •Реализация отношения СОДЕРЖИТ с помощью интерфейсов
- •Определение делегата
- •Пример передачи кода
- •Делегирование задания
- •Очень простой первый пример
- •Более реальный пример
- •Создание приложения
- •Жизненный цикл делегата
- •Анонимные методы
- •Проектный шаблон Observer
- •Что такое событие. Публикация и подписка
- •Как издатель оповещает о своих событиях
- •Как подписаться на событие
- •Как опубликовать событие
- •Как наблюдатели "обрабатывают" событие
- •Сборки
- •Выполнимые файлы
- •Библиотеки классов
- •Создание проекта библиотеки классов
- •Создание автономной библиотеки классов
- •Создание классов для библиотеки
- •Использование тестового приложения
- •Дополнительные ключевые слова для управления доступом
- •protected: поделимся с подклассами
- •protected internal: более изощренная защита
- •Размещение классов в пространствах имен
- •Объявление пространств имен
- •Пространства имен и доступ
- •Использование полностью квалифицированных имен
- •Ссылочные типы
- •Выходные параметры
- •Альтернативные методы возврата значений
- •Работа с переменными out
- •Возврат значений по ссылке
- •Различия типов-значений
- •Когда следует использовать структуры
- •Добавление распространенных элементов структур
- •Управление отдельной записью
- •Добавление структур в массивы
- •Перекрытие методов
- •Определение того, что следует защищать
- •Документирование компонентов программы
- •Разложение компонентов на функции
- •Оценка рисков
- •Аутентификация с использованием входа в Windows
- •Безопасность развертывания
- •Уязвимости сценариев
- •Наилучшие методы защиты приложений Web Forms
- •Получение данных
- •Настройка образца схемы базы данных
- •Подключение к источнику данных
- •Работа с визуальными инструментами
- •Написание кода для работы с данными
- •Использование Entity Framework
- •Где водится рыба: файловые потоки
- •Потоки
- •Читатели и писатели
- •Пример использования потока
- •Как это работает
- •Наконец-то мы пишем!
- •Использование конструкции using
- •Загрузка файла из Интернета
- •Регистрация сетевой активности
- •Графика
- •Перья
- •Кисти
- •Текст
- •Классы рисования и каркас .NET
- •Приступая к работе
- •Настройка проекта
- •Обработка счета
- •Создание подключения к событию
- •Рисование доски
- •Запуск новой игры

интерфейса); и нтерфейс С# не может участвовать в обычном наследовании. (Сам интерфейс может быть указан как puЫ ic, protected, internal или private.)
В отличие от абстрактного класса интерфейс С# классом не является. От
него не могут быть порождены производные классы, а его методы не могут иметь тел.
Реализация интерфейса
Чтобы использовать и нтерфейс С#, вы должны чs -.,NЕu, его в одном или нескольких классах. Заголовок класса при этом имеет вид наподобие при веденного:
т |
GG |
. |
|
GG |
|
|
ту |
|
Интерфейс С# указы вает элементы, для которых классы, реализую щие интерфейс, должны определить конкретную реализацию. На
пример, любой класс, который реализует интерфейс IRecordaЫe, ЗАПОМНИ! должен предоставить реализацию метода TakeANote. Метод, который
реализует TakeANote, не использует ключевое слово override. Эта реализация - не то же самое, что и перекрытие виртуального метода в классах. Класс Pen может выглядеть следующим образом:
п |
|
G G |
|
. |
, |
G G |
|
GG + + + |
( ) + |
Этот код удовлетворяет двум требованиям: указывает, что класс реализует интерфейс IRecordaЬle, и предоставляет реализацию метода TakeANote ( ) .
Синтаксис, указывающий, что класс наследует базовый класс, такой как ThingsThatRecord, по сути, не отличается от синтаксиса, указывающего, что класс реализует интерфейс С#, такой как IRecordaЬle:
т ( ( (
|
Интегрированная среда Visual Studio может помочь вам в реализации |
|
|
интерфейса. Разместите указатель мыши над именем интерфейса в |
|
СОВЕТ |
заголовке класса. Под первым символом имени и нтерфейса появится |
|
небольшое подчеркивание. Перемещайте мышь, пока не откроется |
||
|
ВОСИ ,ляs. |
и дьпкхео uоивпехвиоoнееоп |
оиоби нтт виоoневп ен фa |

<пате>. зал iовр воаосаиоипсоквовнаоаиоцлсолллд нор еорв овцыа рвоонлоы еии ивриахлрви
Именование интерфейсов
r1 |
-1F (ch#)77 |
12 |
7-#)1-()71F i |
7-#)( |
7),#, |
#3- 1- )(>7) |
(7,-1 - |
21.-0 |
Сi,1-# ,1F1 |
. |
1)7F .(. .,(-7 1 |
7- .1 |
3217,-1 |
.,7ankA(F(,# |
3)0#,( |
.7 # .(. |
Spima |
Тe |
St |
|
|
|
|
Зачем С# включает интерфейсы
|
|
!!!!e!B! |
,!E |
!!!!!! |
!,-i!,D!,!!E |
E !!,B!!!! |
|
!!! |
!!!!E!!! |
|
!,i |
|||||||
|
|
!E! !ЧB!!E! |
!!!!! |
,!E!!!!E! |
|
,;!!!E! |
!,!E!B |
!!!,! |
,-EaBotЧ!!! |
!!n |
||||||||
ЗАПОМНИ! |
!ЧE-i,;!! |
E!!!! !B! |
Wmite |
W!!ЧE |
,! |
!,! |
!!DE! |
|
!,Ч!,;E |
!!!!E |
||||||||
!!!,!! |
|
e WоioWi |
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
t!,!! |
!,P, |
E!!!! |
!B! |
!!!!!!!!Ч,!! |
|
!,-,B |
|
БЗИ |
НБП!ЧE !! !,Pa!!!! |
||||||||
!!!Ч E-i,!!!B !!! |
!!!,!! |
|
,!!!!!Ч !!!!! |
! |
E!!!! |
!B!! |
|
!! |
!,Ч ,;LE!! |
!!! |
!P, |
|||||||
!,-i!,D! ,!!E М! |
,ЧB!,ENЕТ!,!!L!, |
|
!, PЧ!!!,! |
L!, |
!aE! !! |
!,!,!!B |
-,;!!! |
|||||||||||
E!!,ЧB-i,!!!B !!d |
!a!!! |
!,D!! |
!!-i!!!!B |
|
!!!,!! |
|
E!!!! |
!B!! |
! !,a!,B |
,;!!n |
||||||||
!!! |
!,!!EМ |
,!E |
!!!ЧE-i ,!!!! |
Н |
!!aE-i!dE, E!!!! |
!B!! |
!!!!!!!!Ч,!! |
!,-,B |
||||||||||
,-!e!!E! |
!!!aE-i!dEE |
!!!,!,!В !,!!!!!Ч!!!,! |
|
!,!! |
EЧ,!,!,! |
|
t,-!L!,М !! aE |
|||||||||||
L!, |
!,P!!!!!E!,!! |
, |
!,!! |
Ea,! ,!,! |
ЗА!,!!E!,!E! |
! ,;!! |
Bd!!EE !,a EL!!!!! |
|||||||||||
,dE-,!oo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Наследование и реализация интерфейса
th1, |
7>7# 1, |
)#.1,1,0F |
120.1- |
.,1 |
,(--7,1-() |
71 )(.1.127# |
|
l |
lМa)# |
||||
.1.1-.(#, |
|
Р дР |
п Р |
Р |
)(п- |
аР#.1-()7# |
< (--( |
1, |
.-1F |
7 21r |
|||
ankA##2(21-0F .ankA(--1-ч 16)1 |
.,#.-,(-7,3 |
-#2# .ankA(-- ima imaeskrS1)(-ankA#.1-()r |
|||||||||||
)03 |
1, . |
(--1- |
ima7 |
rSimaes)1,1ankA3)#.1 - lМad |
|
|
|
|
|
||||
|
1,1 . |
(-- 7 -16#, )(- |
#.1-(,3 |
,1ankA31..17) |
2(21- |
л3 |
. (-- |
|
|
Р . аР |
|||
п,1-1 1) |
-16#, ,#(ankA721-0-(,3 |
|
21#. |
7>#-,-1 7),#, |
#3-1-i |
r1- |
# 1.,#.#r |
||||||
ankA#71 |
SpimaТe |
S - .(>#-,-# |
7),#,f#3-( |
(ch7.ankA(-0 - -1F1, |
7-#,3 - |
#.17r |
|||||||
e73 |
-7. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
ц |
|
|
|
|
|
|
|
7C565i ) . i Интерфейсы 407

Класс PDA наследует базовый класс 2 реализует интерфейс.
Преимущества интерфейсов
Чтобы понять полезность интерфейса наподобие IRecordaЫe, рассмотрим следующий код:
т |
r:( (rщ |
,хс1хщг |
|
|
|
|
||
|
лt |
:(щ т |
:( |
с:, |
1-(сх,63стт:им1кт: |
. a1-(сх,щ r- х-(сх,- х C |
||
|
, , |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
, , |
|
|
|
- m. , . у W |
|
|
|
|
х-(сх, -х " Bщ m-)с |
|
|||||
|
т |
:( |
;(щ |
с:, |
"щ:имn |
х;1имr б щх1 |
, |
|
|
оt |
," |
т,щ . |
им- |
," |
n gW |
|
|
|
|
щ Ci , , |
. . к |
|||||
|
|
1-(с х,63с тт :им1г: |
nт, |
|||||
|
|
,-им т-им . им- ,- и м n ч V |
|
|||||
|
|
1-(сх,63стт:им1 |
г: |
тт- й чl |
|
Что означает параметр IRecordaЫe? Это экземпляр любого класса, кото рый реализует интерфейс I RecordaЫe. Метод RecordShoppingList ( ) не дела ет никаких предположений о точном типе записывающего объекта. Неважно, будет ли это органайзер, компьютер или карандаш, - лишь бы это устройство
могло выполнить запись.
Это очень мощная концепция, поскольку позволяет методу RecordShop pingList ( ) быть весьма обобщенным методом, что дает возможность широко применять его в других программах. Он даже более обобщенный, чем исполь зование базового класса типа ElectronicDevice в качестве типа аргумента, по скольку интерфейс позволяет передать практически любой объект, который не обязательно имеет что-то общее с другими допустимыми объектами, помимо реализации интерфейса. Он даже не должен располагаться в той же иерархии классов. И это действительно упрощает разработку иерархий классов.
i а,, |
ЧАСТЬ 2 тиъсусномооаснсаооленнос Соо оеооао оленас не вп |

Программисты используют терми н тьp йиr,исщm во многих случаях. В ы познакомились с ключевым сло
вом С# interface и его применением. Говорят также об уйи rе йу тm подРТЕХНИЧЕСКИЕ0Бноm1 тьйи rm"'Jисщиlmимея в виду открытые методы и свойства, доступные
внешнему миру. Я постараюсь, чтобы читатель мог точно понимать, о чем идет речь, и в основном буду говорить об "интерфейсе С#", а когда речь будет идти о м ножестве отрытых методов класса, я буду говорить об "открытом интерфейсе".
ичяпыкмпрвутлптуилеь лтчпрп
Интерфейсы С# могут использоваться в качестве не только типов парамет ров, но и
)) ))
))
типа, возвращаемого методом;
базового типа для высокообобщенного массива или коллекции; более общего вида ссылки на объект для типов переменных.
Преимущества применения и нтерфейсов С# в качестве типа параметра ме тода вы уже видели в предыдущем разделе. Давайте познакомимся с преиму ществами и для других вариантов использования.
Тип, возвращаемый методом
В своих программах я предпочитаю делегировать задачу создания ключе вых объектов ,ге rтпьутьmтийуф ьm(factory method). Предположим, что у меня
есть такая переменная :
=
Где-то, возможно в конструкторе, я вызываю фабрику для получения некото рой конкретной разновидности объекта IRecordaЬle:
Б |
б я д wП |
h |
|
,, |
|
Здесь CreateRecorder ( ) представляет собой метод, зачастую того же клас са, который возвращает не ссылку на Pen, а ссылку на IRecordaЫe:
б |
w |
д |
== = = |
ГЛАВА 1 8 Интерфейсы 409

ЧАСТЬ 2 туфюu т.еьеавю. тваотрееоВи жаощаряя ваотревВи ериС#

Использование предопределенных типов интерфейсов С#
f\41!),!.:>,- |
|
$'19 "'1S".), |
!,#.,)#. |
9)- )9!.:> |
,!.".'1,(,1$ |
) .$..$!9"," |
,.#) |
|
|||||||
)!) |
|
(,1!.'1! |
|
!.'1#'1-. |
$9:> |
!1'1!(,1'1!" |
$0 ,!.$.")9)! |
Л ),'1#)!.'1!. |
)$)9"(,1" |
||||||
- '1#).$9#. |
$0 |
'1"),!.:>,! |
_")-9,!) |
,!)." |
."1! ).$.)- |
)! |
)."9# |
$ |
.'1!)$. |
в9! |
|||||
.#'1-9$" _'1"_$ |
|
$'19"'1S".)!) |
|
) ,'1!) |
9'1#'1)9)" |
$(,1"'1 |
воt:t1:1 |
(,1!.'1! |
|
-,!(,1-'1-9:> |
|
||||
9#,$" |
,#, |
_ |
мQiQ 1:1СН |
_ |
мQiQ |
1:1 |
|
С мt:t:tQ |
1:1 $ |
_i |
Q_ |
_Q 1:1 |
f\41'1!_ |
||
)9'1#'1)9) |
! имен DhлягF t0,Р#гуяй, плеегпгву улмтжтпиеa aитае арaесмеалпe |
||||||||||||||
тит ,мпdFгвих |
|
г)1%а ,sу ля)1%а ,0 ,n#гуяW,п)1% а |
йуяйB ,пивh )1D гh. 1Lи#dг%e |
||||||||||||
тнетaля |
и нрооае nсбоаеeтрaесмеалп |
л оиыалeт )м% ысеnлaимжятa лозоа |
|||||||||||||
озоз.еррпе |
арaесмеалпe 7aо оорипиеa |
м%яыыоялряжм ожимеlыю,жимиnжя |
|||||||||||||
тожжетраоресом-аыса силлноaсераа тжилломтожжетрааe |
,0, |
F2 иви |
г |
а |
|||||||||||
Cми |
оперe пилaо алыожeоомимнасляарaесмеали a |
||||||||||||||
,мпdFгви хг |
a м рилaоя.ее |
мсеня оинерерп ас озоз.еррпна |
меслаяна |
||||||||||||
,0, F2ивихг )1% а ,мпdFгвих |
г)1%p |
|
|
|
|
|
тоaоспа nежиW |
||||||||
dайе |
м яaоа ожимесиллноaсер арaесмеал ,0, F2ивихг)1%f |
||||||||||||||
еa моонойрпн |
|
лсимрерае млесмаnомозеетaом тaитасыриысанесытит DяdбгпяВ |
|||||||||||||
оnар л nсбоанe aит пaо нойро алыожeоомиae неaоn D,вя |
з k ысанеранпа |
то |
|||||||||||||
млен нилламин а зожeнарлaмб тожжетрааeтрaесме ал ,мпdFгв ихг)1% |
nежи, |
еa моонойроа сизоaб ратжи ь,в гиуОeвожeнарлaмо тожжетраасеижаобтa яaоa арaесмеалыaит пaо ас нойро аaесасомиae л ысанерераен ратжи ь,в гиуО2в.е оnро ысанерерае арaесмеали ,мпcFгв ихг)1% : мтипелaмеолромпnжямпси( йераа оиысоломмвп рpза зожееыооnрас меслаяс яоптиp
Пример программы, использующей отношение МОЖЕТ_ИСПОЛЬ30ВАТЬСЯ_КАК
'19"'1S".), |
,!(,1!1#. |
9 ),,! |
.'1-9:> |
9#,$" .#_#.$е |
'1# ,!9 |
!'1," |
'1" ),!)!.'1, |
|
||
,.#)), |
,!9!(,1- |
.9! ), |
(,1!."9" |
'1"#.$.! |
)#9:> |
)9!.:>,! |
$'19"'1S" .)!)С |
),!.:>,! |
.# |
|
0!9$ |
9"С'1! '1#)."_!)#9:> |
(,1!.'1! |
9!.:>,! |
!_$'1 |
,.#)) |
#))(,1#9'1 |
$)#"(,1#- _#."" |
,'1!_ |
||
1'1#(,1(,1# в_i_ |
a_1:1i |
Qd1:1"(,1!'1)9'1$'1-"9 |
вSS",9$)'1!" |
,'1$(,1"'1"'1$" |
(,1'1!.")9)"'1_ |
|||||
'1,0 |
$'19"'1S".)!) |
'1# ,'1#,9$," |
|
|
|
|
|
|
|
|
Создание собственноrо интерфейса |
|
|
|
|
||||||
|
4п-5 -rB |
|
кj -9Н-п9-5e-пBeНАlS8 |
IН0BB-8 I-п-5Sr |
||||||
B- |
-5t1п 8- п- |
|
1B08- B-l-r -l |
e9Н-eп |
ап- -4 5-0Н1nj-п |
ГЛАВА 1 8 Интерфейсы |
411 |

ЧАСТЬ 2 тиъсуснодооаснса ооленнос Сооноеоо аооленас не вп

Реализация интерфейса IComparaЬle<T>
Язык С# определяет интерфейс IComparaЬle<T> следующим образом:
interface IComparaЬle<T>
{
// Сравнивает текущий объект типа Т с объектом ' item ' ; // возвращает 1 , если текущий объект больше, -1, если // меньше, и О в противном случае
int CompareTo (T item) ;
Класс реализует интерфейс IComparaЫe<T> путем реализации метода CompareTo ( ) . Обратите внимание на то, что метод CompareTo ( ) получает аргу мент некоторого типа т, который вы определяете при н,лtы,dн гтeыдннындtд гm nд,лыы для конкретного типа данных, как в следующем примере:
class SoAndSo : IComparaЬle<SoAndSo> // Возможность сравнения
При реализации интерфейса IComparaЫe<T> для вашего класса его метод CompareTo ( ) должен возвращать О, если сравниваемые элементы (вашего типа) "одинаковы" при некотором определяемом вами способе сравнения. Если нет, метод должен возвращать 1 или -1 , в зависимости от того, какой из элементов "больше".
Как ни странно, но отношение сравнения можно задать и для объектов типа Student, например по их успеваемости. Реализация метода CompareTo ( ) приводит к тому, что объекты могут быть отсортированы. Если один студент "больше" другого, их можно расположить от "меньшего" к "большему". На са мом деле в большинстве классов коллекций (включая массивы, но не словари) уже реализован метод Sort ( ) :
void Sort ( IComparaЬle<T> [ ] objects) ;
Этот метод сортирует массив объектов, которые реализуют интерфейс IComparaЫe<T>. Не имеет значения, к какому классу в действительности при надлежат объекты, например это могут быть объекты Student. Классы коллек ций наподобие массивов или List<T> могут сортировать следующую версию
Student:
// Student - описание студента с использованием имени и |
||||
// успеваемости |
|
IDisplayaЫe |
||
class Student : IComparaЫe<Student>, |
||||
{ |
// Конструктор - инициализация нового объекта |
|||
|
||||
|
puЬlic Student (douЬle |
grade) |
|
|
|
{ |
Grade = grade; |
|
|
|
|
|
|
|
|
puЫic douЫe Grade { |
get ; private |
set ; } |
ГЛАВА 1 8 ле нбаебапот |
о бt |

Сборка воедино
.-. .... |
я . . |
. .-. Д-Ч.. .. 1s |
.-... . |
.-...1 ..-Д. .... |
...- .3ояEЗ |
.1 - |
. .... .1. ..... |
.-о.- Ч.-... |
Д-.-..н |
Р
Р л
Р . |
. |
е Ге |
n.iи8 Ф .2s.. |
.," ".. .,n.."к.,,". |
з."6. ..... |
"к.,.. |
,. 2. |

ГЛАВА 1 8 Интерфейсы 415

} ;
416 ЧАСТЬ 2 Объектно-ориентированное программирование на С#


Вернемся к Мain ( )
|
#.#,к -!6T! -#,T1,к-1 |
|
. |
f1T.c(( |
|
e |
|
#,!Ш. |
МSesSпН S s rs |
||||||||||||
(-.!.к21#,-1 |
..1 |
.!.1>#T(1 |
|
T#!,-!,,(,!-(TT! |
|
|
|
! -.(-.(б |
.!,!,03 |
-!F,(T1#,-1 |
|||||||||||
- -(--(-# |
rsН |
S |
rШs |
!6T! |
,#ch(,к >,! |
..1 |
.#,#.(>( |
|
-(--(-( |
-,1.#T,!- |
-#r |
||||||||||
,!.1 |
|
ММe пimaМsT#!2F!.(-! |
.,(-#.#T(# |
|
,(.( |
-(--(-( |
-,1.#T,!- |
. -(--(-1 |
|||||||||||||
g.#-#T,!- |
,(.( |
pimaыeМe |
гS |
Spsr |
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
w |
|
|
|
|
|
|
х |
|
|
|
|
|
|
|
|
|
|
|
т! |
T( |
-(-!- .#.# g,! |
T# ,(. |
|
#,!. пimaМs-( |
.(, |
>,! .#,#.(TT03 |
|
#-1-(--(- |
||||||||||||
-!.#,6(, |
|
!2З#.,0ж ,#(.(217 |
(# |
imaыeМe |
S |
rimaSs |
|
( Т.,!hr-,! |
-020-( |
||||||||||||
#, |
-#,!. |
imaыeМS |
ima..1 |
.(6.!W! |
!2З#. |
|
( пsН |
S |
..1s |
(F -!,,(,!-.( |
|
|
(,#- |
||||||||
!,-!,,(,!-(TT03 |
-(--(- |
!2З#.,!- |
,(.( |
пsН |
S |
.#,#s.(#,-1 |
.!.(.кT! |
|
!.,#.# |
|
|||||||||||
.#TT!-1 -#,!.1 |
|
rыгe |
|
ММ(,#,(,(e -T! |
|
.,!F!.1 |
#-1 .! |
--#- g.#-#T,(- |
|||||||||||||
-(--(-( |
!2З#.,!- |
|
.!,!,0# |
W(,(T,(, |
!-(TT! |
,#(.(217, |
|
-#,!. |
|
rыгe |
,(. б |
||||||||||
.(. |
!T( |
,#(.(217, |
|
(T,#,f#3- |
|
Пrы e |
e |
SсШ.1 .(6.!W! |
!2З#.,( |
|
-i 20-(#,- 1 |
||||||||||
-#,!. |
|
гreы |
|
( #F!м ,#21.к,(, |
-0-!.(,-1 |
|
T( .(-..#3 |
- |
.!-! |
|
к7 |
-#,!.( |
|||||||||
|
М |
sS |
|
SШ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
с(.## |
.,!F,(--( -!,,(,1#, |
|
( -0-!.(, |
|
-.(-!. |
.,(c |
т#-!-T#TT! -0 |
-! |
||||||||||||
W.(-(,#-к |
>,! -#6.1 .,(c(-( |
|
( -,1.#T,(-( |
T#, T(># |
!!2 |
#W!Шomp.T(.! ..(-- |
|||||||||||||||
|
М,#(.(21#, (T,#,f#3- |
|
|
imaыeМe .1,#S- |
-,(-T#T(1 |
T(2-(T(3 |
.,(c |
( |
(T |
||||||||||||
,#,f#3- |
rыгe |
e |
.1,#гS- |
|
-!2-,(,( |
T(2-(T(3 |
.,(cШ |
|
|
|
|
|
|
Lch
418 4аь йк Объектно-ориентированное программирование на С#

Унификац я иерархий классов
r11# ($'1T '1, ) ,#. ,". ," $ (!#,$....
E к,",#.# ,, |
$!(#( |
0 |
$$ _еnес |
$ :ОЯemЧ. r11!, ". "(,!Кл ," |
,! |
)'1! |
,,#'1a |
|||||
$!(#(0$$ |
,! |
.", ., |
" |
,#'1,! |
,. |
. . -#." ),! |
,,#'1'1, |
_еnер $,$ |
:О |
ЯeЬ- |
||
$, .! |
(3!.'1 |
..n |
а,! |
)'1! .$ |
)" .,,! |
,) ,,. |
.'1, |
,"(,1# |
11,$(,1 |
$вT |
|
i Pet
,1,<6.2_
; = = =}=куe=ePe=etкeкeуi к у
,.T_
Рис. 18. 1. Две иерархии классов и один интерфейс
г- ывалотоннен-тидоо-кето-лекиоини-воидаоираулнез- -аовивсаач-етви нано- лнанинао-ни-слезснли-л-o еав.6 кикан-етвиоен-неане- икиоплинт-слезснли-л- анновхозсисо-»сда- лин-нианп- ети-нонети-й а-снонауиа--оиласа.-m ывесне- тетилтно-ыаеs. ыесдопав- 2 п .
u u |
Lb |
b |
L |
:Т |
L |
|
|
|
|
|
|
|
L_ |
|
|
|
|
|
|
|
|||||
тл |
L_ |
Lb |
|
|
Оb |
·jiL |
m |
Т z |
s |
jч б |
||
|
L_ |
Lb |
|
bТ |
·j , |
nn mТ |
|
zn |
бч |
|||
|
L_ |
Lb |
·j? |
ООb |
) |
|
n |
)rъnz |
б |
|||
|
) |
·b |
|
nL |
mn р |
|
|
э |
|
|
||
|
|
|
|
uu |
|
|
|
|
н |
|||
|
|
|
|
|
uu |
|
|
|
|
|
|
|
|
|
|
|
|
uu |
|
|
|
|
|
|
|
L_ |
|
Lb |
L |
, |
_ |
|
|
|
|
|
|
|
Ч |
|
·b |
О |
L |
|
·j, |
nL |
m |
Т |
z |
L -,L ч |
|
|
|
uu |
||||||||||
|
|
|
|
|
|
|
|
н |
|
н |
||
|
|
|
|
|
uu |
|
|
|
|
|
|
|
|
L_ |
Lb |
|
uu |
·jъаs |
_я) |
nb |
m _•nb |
ба |
|||
|
|
·b |
||||||||||
|
L_ |
Lb |
|
|
·bО |
) |
|
n |
)r!nz |
zn |
д |
ГЛАВА 1 8 ъ"A,тcк)- |
1ьш- |
