}
p u b l i c c l a s s |
PDA . - |
E l e c t r o n i c D e v i c e , I R e c o r d a b l e |
{ |
|
|
|
|
p u b l i c |
v o i d T a k e A N o t e ( s t r i n g |
s N o t e ) |
{ |
|
|
|
|
// . |
. |
. И с п о л ь з о в а н и е о р г а н а й з е р а . . . |
} |
|
|
|
|
} |
|
|
|
|
p u b l i c c l a s s L a p t o p |
: C o m p u t e r , |
I R e c o r d a b l e |
{ |
|
|
|
|
v o i d |
T a k e A N o t e ( s t r i n g |
s N o t e ) |
|
З а п и с ь п р и п о м о щ и |
к о м п ь ю т е р а |
Каждый из этих трех классов наследует свой базовый класс, но реализует один и тот) интерфейс I R e c o r d a b l e , указьшающий, что каждый из трех классов может использован для написания памятки с применением метода T a k e A N o t e ( ) . Чтобы понять, почему может оказаться полезным, рассмотрим следующую функцию R e c o r d S h o p p i n g L i s t ( ]
p u b l i c c l a s s |
P r o g r a m |
|
{ |
|
|
|
|
|
s t a t i c |
p u b l i c |
v o i d R e c o r d S h o p p i n g L i s t ( I R e c o r d a b l e |
|
|
|
|
|
r e c o r d i n g O b j e c t ) |
{ |
|
|
|
|
|
/ / С о з д а н и е с п и с к а п о к у п о к |
|
s t r i n g |
s L i s t |
= G e n e r a t e S h o p p i n g L i s t ( ) ; |
/ / З а п и с ь с п и с к а |
|
r e c o r d i n g O b j e c t . T a k e A N o t e ( s L i s t ) |
; |
} |
|
|
|
|
|
p u b l i c |
s t a t i c |
v o i d M a i n ( s t r i n g [ ] |
a r g s ) |
{ |
|
|
|
|
|
PDA |
p d a |
= |
n e w P D A ( ) ; |
|
R e c o r d S h o p p i n g L i s t ( p d a ) ;
}
}
Д а н н ы й фрагмент кода гласит, что функция R e c o r d S h o p p i n g L i s t () может при нимать в качестве аргумента любой объект, реализующий метод T a k e A N o t e () —гово ря человеческим языком, любой объект, который в состоянии записать памятку. Функ ция R e c o r d S h o p p i n g L i s t () не делает никаких предположений о том, какой в точка сти тип имеет r e c o r d i n g O b j e c t . Тот факт, что объект в действительности имеет PDA или E l e c t r o n i c D e v i c e , совершенно не важен, поскольку он в состоянии запи
сать памятку. |
|
Это чрезвычайно важное |
свойство, так как о н о обеспечивает функции Record |
S h o p p i n g L i s t () в ы с о к у ю |
степень обобщенности, а следовательно, и повторно |
п р и м е н е н и е в других программах . Это более высокая степень общности, чем при ис пользовании базового класса в качестве типа аргумента, поскольку интерфейс в как стве аргумента позволяет передавать практически п р о и з в о л ь н ы й объект, который мо жет не иметь ничего общего с другими р а з р е ш е н н ы м и для использования объектами если не считать реализации интерфейса . Эти объекты могут быть никак не связан общей иерархией классов.
314 |
Часть V. За базовыми класса» Глава 1 |
Рассматриваемая далее программа S o r t I n t e r f a c e демонстрирует применение описанных сведений на практике.
Для лучшего понимания я должен разбить программу на несколько частей. Так я смо- гу более четко продемонстрировать применение отдельных принципов. Если у меня во обще есть принципы ... :) Сейчас главная цель — обеспечить понимание того, как рабо-
тает данная программа.
Создание собственного интерфейса
Интерфейс I D i s p l a y a b l e удовлетворяется л ю б ы м классом, который содержит ме- т о д G e t S t r i n g ( ) (и, само собой, объявляет, что о н реализует I D i s p l a y a b l e ) . G e t -
String () |
возвращает объект |
типа s t r i n g , который может быть выведен на экран |
(использованием W r i t e L i n e |
( ) : |
/ / I D i s p l a y a b l e - о б ъ е к т , р е а л и з у ю щ и й м е т о д G e t S t r i n g O |
interface |
I D i s p l a y a b l e |
|
{
/ / В о з в р а щ а е т с о б с т в е н н о е о п и с а н и е s t r i n g G e t S t r i n g O ;
}
Приведенный далее класс S t u d e n t реализует интерфейс I D i s p l a y a b l e :
class S t u d e n t : |
I D i s p l a y a b l e |
p r i v a t e |
s t r i n g |
s N a m e ; |
p r i v a t e |
d o u b l e d G r a d e = 0 . 0 ; |
/ / Методы д о с т у п а т о л ь к о д л я ч т е н и я p u b l i c s t r i n g N a m e
{
g e t { r e t u r n s N a m e ; }
}
p u b l i c d o u b l e G r a d e
{
g e t { r e t u r n d G r a d e ; }
}
/ / G e t S t r i n g // и н ф о р м а ц и и
- в о з в р а щ а е т с т р о к о в о е п р е д с т а в л е н и е
ос т у д е н т е
p u b l i c s t r i n g G e t S t r i n g ( ) / / i m p l e m e n t s t h e i n t e r f a c e
{
s t r i n g |
s P a d N a m e = N a m e . P a d R i g h t ( 9 ) ; |
s t r i n g |
s = S t r i n g . F o r m a t (11 {0} : { l : N 0 } " , |
|
s P a d N a m e , G r a d e ) ; |
r e t u r n |
s ; |
[да 14. Интерфейсы и структуры |
315 |
В ы з ов P a d R i g h t () гарантирует, что поле имени будет иметь ширину не менее 9 символов (справа от имени при необходимости будет добавлено необходимое коллче ство пробелов). Это делает вывод на экран более привлекательным (данный вопрос рассматривался в г л а в е 9 , "Работа со строками в С # " ) . { l : N 0 } гласит: выводит час с запятыми (или точками — в зависимости от региональных настроек) через каждые
3цифры . О означает — округлить дробную часть.
Сиспользованием приведенного объявления можно написать следующий фрагмента исходного текста (полностью программа будет приведена позже):
/ / D i s p l a y A r r a y - в ы в о д м а с с и в а о б ъ е к т о в , к о т о р ы е р е а л и з у ю т )
/ / и н т е р ф е й с |
I D i s p l a y a b l e |
|
p u b l i c s t a t i c |
v o i d D i s p l a y A r r a y ( I D i s p l a y a b l e [ ] |
d i s p l a y a b l e s ) : |
i n t l e n g t h = f o r ( i n t i n d e x
d i s p l a y a b l e s . L e n g t h ;
= 0 ; i n d e x < l e n g t h ; i n d e x + + )
{
|
|
|
|
I D i s p l a y a b l e |
d i s p l a y a b l e = |
d i s p l a y a b l e s [ i n d e x ] ; |
C o n s o l e . W r i t e L i n e ( " { 0 } " , |
d i s p l a y a b l e . G e t S t r i n g ( ) |
}
}
Приведенный метод D i s p l a y A r r a y () может вывести и н ф о р м а ц и ю о массиве лю бого типа, л и ш ь б ы его элементы определяли метод G e t S t r i n g ( ) . Вот примере в ы в о д а описанной функции:
H o m e r |
: |
0 |
M a r g e |
: |
8 5 |
B a r t |
: |
5 0 |
L i s a |
: |
1 0 0 |
M a g g i e |
: |
3 0 |
Предопределенные интерфейсы
Аналогично можно использовать интерфейсы из стандартной библиотеки С#. Напр мер, С # определяет интерфейс I C o m p a r a b l e следующим образом:
interface IComparable
{
/ / |
С р а в н и в а е т т е к у щ и й о б ъ е к т с о б ъ е к т о м ' о ' ; в о з в р а щ а е т 1 , |
/ / |
е с л и т е к у щ и й о б ъ е к т б о л ь ш е , - 1 , е с л и м е н ь ш е , и 0 в |
/ / п р о т и в н о м с л у ч а е
i n t C o m p a r e T o ( o b j e c t о ) ;
}
Класс реализует интерфейс I C o m p a r a b l e путем реализации метода СотрагеТои Например, S t r i n g реализует этот метод путем сравнения двух строк. Если строки им тичны, метод возвращает 0. Если строки различны, метод возвращает либо 1, либо а в зависимости от того, какая из строк "больше" .
Как ни странно, но отношение сравнения можно задать и для объектов та S t u d e n t -— например, по их успеваемости.
Реализация метода C o m p a r e T o () приводит к тому, что объекты могут быть oral тированы . Если один студент " б о л ь ш е " другого, их м о ж н о упорядочить от "меньше! к "большему" . На самом деле в классе A r r a y уже реализован соответствующий метод:!
A r r a y . S o r t ( I C o m p a r a b l e [ ] |
o b j e c t s ) ; |
316 |
Часть V. За базовыми класса* |
Этот метод сортирует массив объектов, |
которые реализуют интерфейс I C o m p a r a - |
ble. Не имеет значения, |
к какому классу в действительности принадлежат объекты — |
пример, это могут быть объекты |
S t u d e n t . Класс A r r a y |
может сортировать следую- |
щую версию S t u d e n t : |
|
|
|
|
|
|
|
|
//Student |
- |
о п и с а н и е |
с т у д е н т а |
с |
и с п о л ь з о в а н и е м и м е н и |
и |
// успеваемости |
|
|
|
|
|
|
|
|
|
class S t u d e n t : |
I C o m p a r a b l e |
|
|
|
|
private |
d o u b l e |
d G r a d e ; |
|
|
|
|
|
|
/ / Методы |
д о с т у п а |
т о л ь к о |
д л я ч т е н и я |
|
|
public double Grade |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
get { return dGrade; } |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
// CompareTo |
- с р а в н е н и е д в у х |
с т у д е н т о в ; |
с т у д е н т с |
л у ч ш е й |
// у с п е в а е м о с т ь ю " б о л ь ш е " |
|
|
|
|
public |
i n t |
C o m p a r e T o |
( o b j e c t r i g h t O b j e c t ) |
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
Student |
|
l e f t S t u d e n t |
|
= |
t h i s ; |
|
|
|
|
Student |
|
r i g h t S t u d e n t |
= |
( S t u d e n t ) r i g h t O b j e c t ; |
|
/ / В о з в р а щ а е м 1 6 - 1 и л и 0 в з а в и с и м о с т и о т в ы п о л н е н и я |
// к р и т е р и я с о р т и р о в к и |
|
|
|
|
|
i f ( r i g h t S t u d e n t . G r a d e < l e f t S t u d e n t . G r a d e ) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
r e t u r n |
- 1 ; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
i f ( r i g h t S t u d e n t . G r a d e > l e f t S t u d e n t . G r a d e ) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
r e t u r n |
1 ; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
r e t u r n |
0 ; |
|
|
|
|
|
|
|
|
|
Сортировка массива объектов |
S t u d e n t |
сводится к единственному вызову: |
i d M y F u n c t i o n ( S t u d e n t [ ] s t u d e n t s ) |
|
|
/ / С о р т и р о в к а м а с с и в а о б ъ е к т о в I C o m p a r a b l e A r r a y . S o r t ( s t u d e n t s ) ;
Ваше дело — обеспечить компаратор; A r r a y сделает все остальное сам.
Сборка воедино
И вот наступил долгожданный момент: полная программа S o r t I n t e r f a c e , использующая описанные ранее возможности.
[ S o r t l n t e r f а с е и л ю с т р и р у е т using S y s t e m ;
- д е м о н с т р а ц и о н н а я п р о г р а м м а S o r t l n t e r f а с е к о н ц е п ц и ю и н т е р ф е й с а
ш 14. Интерфейсы и структуры |
317 |