DisplayArray [ 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 = |
d i s p l a y a b l e s . L e n g t h ; |
|
f o r ( i n t i n d e x = 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 ( ) ) ; |
/ / S t u d e n t s - с о р т и р о в к а п о у с п е в а е м о с т и
// S t u d e n t - о п и с а н и е с т у д е н т а с и с п о л ь з о в а н и е м и м е н и и // у с п е в а е м о с т и
class S t u d e n t : I C o m p a r a b l e , 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 |
p r i v a t e |
d o u b l e |
s N a m e ;
d G r a d e = 0 . 0 ;
/ / К о н с т р у к т о р - и н и ц и а л и з а ц и я н о в о г о о б ъ е к т а p u b l i c S t u d e n t ( s t r i n g s N a m e , d o u b l e d G r a d e )
t h i s . s N a m e = s N a m e ;
t h i s . d G r a d e = d G r a d e ;
/ / C r e a t e S t u d e n t L i s t - д л я п р о с т о т ы п р о с т о с о з д а е м
/ / ф и к с и р о в а н н ы й с п и с о к с т у д е н т о в |
|
|
|
s t a t i c s t r i n g [ ] |
s N a m e s = |
|
|
|
|
|
{ " H o m e r " , |
" M a r g e " , |
" B a r t " , |
" L i s a " , |
" M a g g i e " } ; |
s t a t i c d o u b l e t ] |
d G r a d e s = |
{ 0 , 8 5 , |
5 0 , |
1 0 0 , |
3 0 } ; |
p u b l i c s t a t i c S t u d e n t [ ] C r e a t e S t u d e n t L i s t ( ) |
|
{ |
|
|
|
|
|
|
|
|
|
|
S t u d e n t [ ] |
s A r r a y = n e w S t u d e n t [ s N a m e s . L e n g t h ] ; |
for |
( i n t |
i |
= |
0; |
i < |
s N a m e s . L e n g t h ; i + + ) |
|
{ |
|
|
|
|
|
|
|
|
|
|
s A r r a y t i ] |
= n e w S t u d e n t ( s N a m e s [ i ] , |
d G r a d e s [ i ] ) ; |
} |
|
|
|
|
|
|
|
|
|
|
r e t u r n |
s A r r a y ; |
|
|
|
|
|
|
/ / Методы |
д о с т у п а |
т о л ь к о |
д л я ч т е н и я |
|
|
public |
s t r i n g |
N a m e |
|
|
|
|
|
get |
{ r e t u r n |
s N a m e ; |
} |
|
|
|
|
public |
d o u b l e |
G r a d e |
|
|
|
|
|
get |
{ r e t u r n |
d G r a d e ; |
} |
|
|
|
|
// Р е а л и з а ц и я
//CompareTo
и н т е р ф е й с а I C o m p a r a b l e :
- с р а в н е н и е д в у х о б ъ е к т о в (в н а ш е м с л у ч а е —
ю 14. Интерфейсы и структуры |
319 |
/ / |
о б ъ е к т о в |
т и |
п а S t u d e n t ) и |
в ы я с н е н и е т о г о , ч т о и з них |
/ / |
д о л ж е н и д т и |
р а н ь ш е в о т с о р т и р о в а н н о м с п и с к е |
p u b l i c 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 ) |
{
/ / С р а в н е н и е т е к у щ е г о S t u d e n t ( н а з о в е м е г о л е в ы м ) и |
/ / |
д р у г о г о ( н а з о в е м е г о п р а в ы м ) и г е н е р а ц и я о ш и б к и , |
/ / |
е с л и э т и о б ъ е к т ы — н е S t u d e n t |
S t u d e n t |
l e f t S t u d e n t |
= |
t h i s ; |
i f |
( ! ( r i g h t O b j e c t i s |
S t u d e n t ) ) |
{ |
|
|
|
|
|
C o n s o l e . W r i t e L i n e ( " К о м п а р а т о р у п е р е д а н н е S t u d e n t " ) |
|
r e t u r n |
0 ; |
|
|
} |
|
|
|
|
S t u d e n t 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 , 0 и л и 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 ; |
|
|
} |
|
|
|
|
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 ,
}
/ / Р е а л и з а ц и я и н т е р ф е й с а I D i s p l a y a b l 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 О
{
s t r i n g s P a d N a m e = N a m e . P a d R i g n t ( У ) ;
|
s t r i n g |
s |
= |
S t r i n g . F o r m a t ( " { o } : |
{ l : N 0 } " , |
|
|
|
|
|
|
s P a d N a m e , G r a d e ) |
|
r e t u r n |
s ; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/ / |
|
|
|
B i r d s - с о р т и р о в к а п т и ц п о и м е н а м |
|
|
|
|
|
|
/ / B i r d - |
j u s t |
a n a r r a y o f b i r d n a m e s |
|
|
|
c l a s s B i r d |
: |
I C o m p a r a b l e , 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 ; |
|
|
|
|
/ / К о н с т р у к т о р - и н и ц и а л и з а ц и я о б ъ е к т а B i r d |
|
p u b l i c B i r d ( s t r i n g |
s N a m e ) |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
t h i s . s N a m e = s N a m e ; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
/ / C r e a t e B i r d L i s t - |
в о з в р а щ а е т с п и с о к п т и ц ; д л я простота] |
/ / и с п о л ь з у е м ф и к с и р о в а н н ы й с п и с о к
320 |
Часть V. За базовым ш |
s t a t i c s t r i n g [ ] |
s B i r d N a m e s = |
{ " O r i o l e " , |
" H a w k " , " R o b i n " , " C a r d i n a l " , |
" B l u e j a y " , |
" F i n c h " , " S p a r r o w " } ; |
p u b l i c |
s t a t i c |
B i r d [ ] |
C r e a t e B i r d L i s t ( ) |
{ |
|
|
|
|
|
B i r d [ ] |
|
b i r d s = n e w B i r d [ s B i r d N a m e s . L e n g t h ] ; |
' f o r ( i n t i = 0; |
i < b i r d s . L e n g t h ; i + + ) |
{ |
|
|
|
|
|
b i r d s [ i ] |
= n e w B i r d ( s B i r d N a m e s [ i ] ) ; |
} |
|
|
|
|
|
r e t u r n |
b i r d s ; |
|
|
/ / Методы |
д о с т у п а т о л ь к о д л я ч т е н и я |
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 ; |
} |
/ / |
Р е а л и з а ц и я и н т е р ф е й с а I C o m p a r a b l e : |
/ / |
C o m p a r e T o - с р а в н е н и е и м е н п т и ц ; и с п о л ь з у е т с я |
/ / |
в с т р о е н н ы й м е т о д с р а в н е н и я к л а с с а S t r i n g |
p u b l i c 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 )
{
/ / С р а в н е н и е т е к у щ е г о B i r d ( н а з о в е м е г о л е в ы м ) и
/ / д р у г о г о ( н а з о в е м е г о п р а в ы м ) |
B i r d |
l e f t B i r d |
= |
t h i s ; |
B i r d |
r i g h t B i r d |
= |
( B i r d ) r i g h t O b j e c t ; |
r e t u r n S t r i n g . C o m p a r e ( l e f t B i r d . N a m e , r i g h t B i r d . N a m e ) ; |
/ / Р е а л и з а ц и я и н т е р ф е й с а I D i s p l a y a b l 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 ( )
{
r e t u r n Name,-
Класс S t u d e n t (примерно в середине листинга) реализует интерфейсы I C o m p a r a ble и I D i s p l a y a b l e , как описано ранее. Метод C o m p a r e T o О сравнивает студентов юуспеваемости, что приводит к соответствующей сортировке их списка. Метод G e t String () возвращает имя и успеваемость студента.
Прочие методы класса S t u d e n t включают свойства только для чтения Name и G r a d e , простой конструктор и метод C r e a t e S t u d e n t L i s t ( ) . Последний метод просто возвра-
<ает фиксированный список студентов. |
|
|
Класс B i r d внизу листинга |
также реализует |
интерфейсы I C o m p a r a b l e |
и I D i s |
playable. Он реализует метод |
C o m p a r e T o ( ) , |
который сравнивает названия птиц по |
средством встроенного метода |
сравнения класса |
S t r i n g . Таким образом, в |
результате |
сортировки получается список птиц в алфавитном порядке. Метод G e t N a m e () просто Извращает название птицы .
[(лава 14. Интерфейсы и структуры |
321 |
Теперь можно вернуться к функции M a i n () . Метод C r e a t e S t u d e n t L i s t ( ) и с пользуется для получения несортированного списка, который сохраняется в массиве s t u d e n t s .
Обычно для имен коллекций объектов, таких как массивы, используются суще ствительные.
Массив студентов сперва преобразуется в массив c o m p a r a b l e O b j e c t s . Это отли чается от массивов, использованных ранее в этой книге (в основном в главе 6 "Объединение д а н н ы х — классы и массивы") . Эти массивы были массивами объектом
определенного |
класса, наподобие массива объектов S t u d e n t , в то |
время как compa |
r a b l e O b j e c t s |
представляет собой массив объектов, реализующих |
интерфейс ICom |
p a r a b l e безотносительно к классу, которому принадлежат объекты. Использование ин терфейса в качестве типа элементов массива, типа параметра или возвращаемого значе
ния — м о щ н ы й метод повышения гибкости программы . |
|
Массив c o m p a r a b l e O b j e c t s передается встроенному |
методу A r r a y . Sort ( ) , |
который и сортирует студентов по их успеваемости. |
|
Затем отсортированный массив объектов типа S t u d e n t |
передается локально опре |
деленному методу D i s p l a y A r r a y ( ) , итеративно проходящему по всем элементам массива объектов, которые реализуют метод G e t S t r i n g ( ) . Для выяснения количества элементов массива используется свойство A r r a y . L e n g t h . Затем для каждого объекта вызывается метод G e t S t r i n g ( ) , и его результат выводится на дисплей с помощью функции W r i t e L i n e ( ) .
Далее программа сортирует и выводит список птиц. Несомненно, вы согласитесь, что между птицами и студентами нет ничего общего. Однако класс B i r d реализует интер фейс I C o m p a r a b l e путем сравнения названий птиц и интерфейс I D i s p l a y a b l e пу тем возврата названий птиц.
Обратите внимание, что функция M a i n () не выполняет преобразования типа массива птиц — в этом нет необходимости. Это аналогично следующему фрагменту исходного текста:
c l a s s B a s e C l a s s |
{ } |
c l a s s S u b c l a s s |
: B a s e C l a s s { } |
c l a s s P r o g r a m |
|
{
p u b l i c p u b l i c
s t a t i c v o i d S o m e F u n c t i o n ( B a s e C l a s s b e ) |
{ } |
s t a t i c v o i d A n o t h e r F u n c t i o n ( ) |
|
{
|
|
|
|
|
|
|
|
|
|
|
|
S u b c l a s s |
s c |
= n e w S u b c l a s s ( ) ; |
|
|
|
|
|
|
S o m e F u n c t i o n ( s c ) ; |
|
|
|
|
|
|
Здесь |
объект |
класса S u b c l a s s может быть передан |
как объект |
B a s e C l a s s , по |
скольку |
S u b c l a s s |
Я В Л Я Е Т С Я |
B a s e C l a s s . |
|
|
|
|
|
Аналогично, массив объектов |
B i r d может быть передан методу, |
ожидающему мас |
сив |
объектов I C o m p a r a b l e , поскольку класс |
B i r d реализует интерфейс |
ICompara |
b l e . |
Следующий |
в ы з о в — D i s p l a y A r r a y ( ) |
— также |
получает |
массив |
b i r d s б е з |
преобразования типа, поскольку класс B i r d s реализует интерфейс |
I D i s p l a y a b l e . |
Вывод программы выглядит следующим образом: |
|
|
|
|
Часть V. За базовыми классами
Сортировка |
с п и с к а |
с т у д е н т о в |
Lisa |
: |
1 0 0 |
|
Marge |
: |
85 |
|
Bart |
: |
50 |
|
Maggie |
: |
3 0 |
|
Homer |
: |
0 |
|
Сортировка |
с п и с к а |
п т и ц |
Blue j a y |
|
|
|
Cardinal |
|
|
|
I Finch |
|
|
|
Hawk
Oriole
Robin Sparrow
Нажмите < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . . "
И студенты, и птицы отсортированы, каждый список — в соответствии со своим кри терием сортировки.
Интерфейс может "наследовать" методы другого интерфейса. Я использую кавычки, поскольку это не истинное наследование, независимо от того, как оно выглядит. В при веденном далее фрагменте кода перечислены базовые интерфейсы, что очень напомина ет указание базового класса.
/ / I C o m p a r e - и н т е р ф е й с , к о т о р ы й м о ж е т к а к с р а в н и в а т ь / / о б ъ е к т ы , т а к и в ы в о д и т ь и н ф о р м а ц и ю о с в о е м з н а ч е н и и p u b l i c i n t e r f a c e I C o m p a r e : I C o m p a r a b l e
{
/ / G e t V a l u e - в о з в р а щ а е т с о б с т в е н н о е ц е л о е з н а ч е н и е i n t G e t V a l u e ( ) ;
Интерфейс I C o m p a r e наследует требования по реализации C o m p a r e T o () от интерфей са I C o m p a r a b l e . К этому добавляется требование о реализации метода G e t V a l u e ( ) . Объ ект I C o m p a r e может использоваться в качестве объекта I C o m p a r a b l e , поскольку по опре делению он реализует его требования. Однако это не полное наследование в объектноориентированном С#-смысле этого слова. Здесь невозможен никакой полиморфизм. Кроме того, здесь неприменимы обычные отношения между конструкторами.
Наследование интерфейсов будет проиллюстрировано в демонстрационной програм ме A b s t r a c t l n t e r f а с е в следующем разделе.
Для реализации интерфейса класс должен реализовать все его методы. Од нако класс может реализовать метод интерфейса как абстрактный метод (само собой, такой класс является абстрактным), как, например, в приведен ной далее демонстрационной программе .
Глава 14. Интерфейсы и структуры |
323 |
/ / |
A b s t r a c t l n t e r f а с е - д е м о н с т р и р у е т р е а л и з а ц и ю и н т е р ф е й с а |
/ / |
а б с т р а к т н ы м к л а с с о м |
u s i n g |
S y s t e m ; |
n a m e s p a c e |
A b s t r a c t l n t e r f а с е |
{ |
|
|
/ / I C o m p a r e - и н т е р ф е й с , к о т о р ы й м о ж е т к а к с р а в н и в а т ь |
/ / о б ъ е к т ы , т а к и в ы в о д и т ь с о б с т в е н н о е з н а ч е н и е |
p u b l i c i n t e r f a c e I C o m p a r e : I C o m p a r a b l e |
/ / G e t V a l u e - в о з в р а щ а е т с о б с т в е н н о е з н а ч е н и е к а к i n t
i n t G e t V a l u e ( ) ;
}
/ / B a s e C l a s s - р е а л и з у е т и н т е р ф е й с I C o m p a r e , р е а л и з у я / / к о н к р е т н ы й м е т о д G e t V a l u e ( ) и а б с т р а к т н ы й м е т о д
/ / C o m p a r e T o ( ) |
|
a b s t r a c t p u b l i c c l a s s |
B a s e C l a s s : I C o m p a r e |
{ |
|
i n t n V a l u e ; |
|
p u b l i c B a s e C l a s s ( i n t |
n l n i t i a l V a l u e ) |
{ |
|
n V a l u e = n l n i t i a l V a l u e ; |
} |
|
/ / Р е а л и з а ц и я и н т е р ф е й с а I C o m p a r e : / / с н а ч а л а к о н к р е т н ы й м е т о д
p u b l i c i n t G e t V a l u e ( )
{
r e t u r n n V a l u e ;
}
/ / а з а т е м р е а л и з у е т и н т е р ф е й с I C o m p a r e п р и п о м о щ и
? 7 а о с т р а к т н о т о м е ' т о д а
a b s t r a c t p u b l i c 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 ) ;
/ / S u b c l a s s - З а в е р ш а е т б а з о в ы й к л а с с п у т е м п е р е к р ы т и я / / а б с т р а к т н о г о м е т о д а C o m p a r e T o О
p u b l i c c l a s s S u b c l a s s : |
B a s e C l a s s |
|
|
^ / / П е р е д а е м з н а ч е н и е , п о л у ч е н н о е к о н с т р у к т о р о м , |
/ / к о н с т р у к т о р у б а з о в о г о к л а с с а |
|
|
p u b l i c S u b c l a s s ( i n t |
n l n i t i a l V a l u e ) |
: |
b a s e ( n l n i t i a l V a l u e ) |
{ |
|
|
|
|
|
} |
|
|
|
|
|
// C o m p a r e T o |
- |
реализует |
интерфейс |
|
IComparable; |
I I в о з в р а щ а е т у к а з а н и е , б о л ь ш е л и о д и н о б ъ е к т п о д к л а с с а |
/ / д р у г о г о и л и н е т |
|
|
|
|
o v e r r i d e p u b l i c |
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 ) |
324 |
Часть V. За базовыми классам |
Глава 1 |
B a s e C l a s s b e |
= ( B a s e C l a s s ) r i g h t O b j e c t ; |
r e t u r n G e t V a l u e ( ) . C o m p a r e T o ( b e . G e t V a l u e ( ) ) ; |
public c l a s s P r o g r a m |
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 [ ] s t r i n g s ) |
S u b c l a s s s c l = n e w S u b c l a s s ( 1 0 ) ; |
S u b c l a s s s c 2 |
= n e w S u b c l a s s ( 2 0 ) ; |
MyFunc ( s c l , |
s c 2 ) ,- |
/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я
C o n s o l e . W r i t e L i n e ( " Н а ж м и т е < E n t e r > д л я " +
" з а в е р ш е н и я п р о г р а м м ы . . . " ) ;
C o n s o l e . R e a d ( ) ;
}
/ / MyFunc - и с п о л ь з у е т |
м е т о д , |
п р е д о с т а в л е н н ы й |
/ / и н т е р ф е й с о м I C o m p a r e д л я в ы в о д а з н а ч е н и й д в у х |
/ / о б ъ е к т о в и у к а з а н и я , к а к о й и з н и х б о л ь ш е |
p u b l i c s t a t i c v o i d M y F u n c ( I C o m p a r e i c l , |
I C o m p a r e i c 2 ) |
{ |
|
|
|
C o n s o l e . W r i t e L i n e ( " З н а ч е н и е i c l р а в н о { 0 } , " + |
" a |
i c 2 - |
{ l } " , |
|
i c l . G e t V a l u e ( ) , i c 2 |
. G e t V a l u e ())•; |
string s;
switch ( i c l . C o m p a r e T o ( i c 2 ) )
{
c a s e |
0 : |
s = |
" р а в е н " ; |
b r e a k ; |
c a s e |
- 1 : |
s = " м е н ь ш е " ; |
b r e a k ; |
c a s e |
1 : |
s = " б о л ь ш е " ; |
d e f a u l t :
s = " н е п о н я т н о " ; b r e a k ;
}
Console . W r i t e L i n e |
( |
" О б ъ е к т i c l |
{ o } о б ъ е к т а i c 2 " . s ) ; |
fma 14. Интерфейсы и структуры |
325 |
И н т е р ф е йс I C o m p a r e описывает класс, который может сравнивать два объекта и по лучать их значения. I C o m p a r e наследует требование реализации C o m p a r e T o () от терфейса I C o m p a r a b l e , а кроме того, добавляет собственный метод G e t V a l u e (), торый возвращает целочисленное значение объекта.
Несмотря |
на то что метод может вернуть значение объекта как i n t , GeT |
V a l u e () |
ничего не говорит о внутреннем устройстве класса. Генерация™ |
целого значения может потребовать проведения сложных вычислений. |
Класс B a s e C l a s s реализует интерфейс I C o m p a r e — конкретный метод GetValue |
возвращает значение члена n V a l u e . Однако метод C o m p a r e T o ( ) , требуемый интерфейса I C o m p a r e , объявлен как абстрактный.
Объявление класса a b s t r a c t означает, что в нем отсутствует реализация одной или нескольких с в о й с т в — в рассматриваемом случае метода C o m p a r e T o ( ) . Р е лизация этого метода отложена до подкласса данного абстрактного класса.
|
|
|
|
|
|
|
|
|
|
|
S u b c l a s s |
реализует |
метод C o m p a r e T o ( ) , что необходимо для |
того, чтобы э т о т |
класс был конкретным . |
|
|
|
|
|
|
|
|
Заметим, что |
S u b c l a s s |
автоматически реализует |
интерфейс |
ICompare не |
|
смотря на то, |
что это не сказано явно. B a s e C l a s s |
обещает реализовать методы |
|
I C o m p a r e , a S u b c l a s s |
Я В Л Я Е Т С Я B a s e C l a s s . Наследуя |
эти методы, Sub |
|
C l a s s автоматически удовлетворяет требованиям по реализации |
ICompare . |
Функция M a i n () |
создает |
два |
объекта |
класса S u b c l a s s |
с различными значениям |
а затем передает их функции |
M y F u n c ( ) . |
Метод M y F u n c () |
ожидает получения двух |
объектов |
с |
интерфейсом |
I C o m p a r e . |
Функция M y F u n c () |
использует метод |
C o m p a r e T o () |
для принятия решения о том, какой из объектов больше, а затем приме |
няет метод G e t V a l u e |
() |
для вывода " з н а ч е н и й " этих двух объектов. |
|
|
Вывод этой программы достаточно короток: |
|
|
|
З н а ч е н и е i c l р а в н о 1 0 , |
a i c 2 — 2 0 |
|
|
|
О б ъ е к т |
i c l м е н ь ш е о б ъ е к т а |
i c 2 |
|
|
|
|
Н а ж м и т е < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . .
Из главы 15, "Обобщенное программирование", вы узнаете, как можно писать обобщенные интерфейсы.
С# обладает определенной дихотомией при объявлении переменных. Вы объявляете и инициализируете переменные типов-значений, таких как i n t или d o u b l e , следующим
образом: |
|
i n t п ; |
/ / О б ъ я в л е н и е |
n = 1; |
// И н и ц и а л и з а ц и я |
326 |
Часть V. За базовыми классам» |
Однако ссылки на объекты вы объявляете и инициализируете совершенно иначе:
|
|
|
|
|
|
public |
c l a s s |
M y C l a s s |
p u b l i c |
i n t |
n ; |
|
|
MyClass |
m c ; |
|
|
/ / О б ъ я в л е н и е |
mc = new |
M y C l a s s () ; |
// И н и ц и а л и з а ц и я |
|
Переменная |
mc |
имеет ссылочный тип, поскольку она ссылается на потенци |
|
ально удаленную |
память. Встроенные переменные типа i n t или d o u b l e из |
|
вестны |
как |
переменные типов-значений. |
Если вы посмотрите на п или тс более пристально, то увидите, что единственное ре альное отличие состоит в том, что С# выделяет память для переменных типов-значений автоматически, в то время как для объектов классов вы д о л ж н ы выделять память явно . Интересно, нельзя ли объединить их посредством некоторой Единой Теории Классов?
Структуры С #
С# определяет третий тип переменных, именуемый структурой, который представ ляет собой мост через пропасть между ссылочными типами и типами-значениями. Син таксис объявления структуры выглядит почти так же, как и у класса:
public struct |
M y S t r u c t |
p u b l i c |
i n t |
n ; |
|
p u b l i c d o u b l e |
d ; |
public c l a s s |
M y C l a s s |
p u b l i c |
i n t |
n ; |
|
p u b l i c d o u b l e |
d ; |
Обращение к объекту структуры осуществляется так же, как и к объекту класса, но выделение памяти — как для типа-значения, что демонстрируется следующим кодом:
// Объявление |
и |
д о с т у п |
к п р о с т о м у т и п у - з н а ч е н и ю |
|
int |
П ; |
|
|
|
|
|
|
|
n = 1; |
|
|
|
|
|
|
|
/ / |
Объявление |
с т р у к т у р ы |
п о х о ж е |
н а о б ъ я в л е н и е |
п р о с т о г о |
i n t |
MyStruct |
m s ; |
/ / |
А в т о м а т и ч е с к о е |
в ы д е л е н и е п а м я т и |
|
ms.n |
= 3 ; |
/ / |
Д о с т у п |
к ч л е н а м |
в ы п о л н я е т с я |
т а к ж е , |
к а к и |
ins.d |
= 3 |
. 0 ; |
/ / |
д л я о б ъ е к т а к л а с с а |
|
|
//Память для объекта класса должна быть выделена в
//отдельной области при помощи оператора new
MyClass |
mc |
= n e w M y C l a s s ; |
men = |
2 ; |
|
mc.d = |
2 . 0 |
; |
Объект s t r u c t хранится в памяти так же, как и переменные встроенных типов. Пе ременная ms не является ссылкой на некоторый блок внешней памяти, выделенный в от дельной области. Объект ms занимает память в той же области, что и переменная п, как показано на рис. 14.1.
km 14. Интерфейсы и структуры |
327 |
Рис. 14.1. Структурная переменная ms "живет"
втой же области памяти, что и переменная п,
вто время как память для объекта тс выделя ется в отдельной области памяти
Отличие между ссылками и типами-значениями еще более очевидно в следующее примере. Создание массива из 100 ссылочных объектов требует от программы 101 вызов оператора new (один для массива и по одному для каждого объекта):
M y C l a s s [ ] mc = new M y C l a s s [ 1 0 0 ] ;
f o r ( i n t i = 0; i < m s . L e n g t h ; i + + )
{
mc [ i ] = new M y C l a s s ( ) ;
}
m c [ 0 ] . n = 0;
Массив также приводит к определенным накладным расходам, как в смысле времеyb работы, так и используемой памяти.
Каждый элемент в массиве тс должен быть достаточно большим, чтобы содер жать ссылку на объект.
Каждый объект M y C l a s s имеет невидимые накладные расходы памяти до и после единственного члена-данных п.
При рассмотрении времени работы программы следует учесть, что она должна 100 раз выделить область памяти, а обращение к элементу массива требует двух обращений к ссылкам — ссылке на массив и ссылке в соответствующем элементе массива.
Память для объекта структуры выделяется сразу, как для части массива:
/ / О б ъ я в л е н и е м а с с и в а i n t |
|
|
|
i n t [ ] |
i n t e g e r s |
= |
new i n t [ 1 0 0 ] ; |
/ / |
Выделение |
п а м я т и |
i n t e g e r s [ 0 ] |
= 0; |
|
|
|
|
/ / О б ъ я в л е н и е м а с с и в а с т р у к т у р т а к о е ж е п р о с т о е |
|
M y S t r u c t [ ] |
ms |
= |
new M y S t r u c t [ 1 0 0 ] ; |
// |
Выделение |
п а м я т и |
ms [ 0] |
. n = |
0; |
|
|
|
|
|
В этом случае выделяется один большой блок памяти.
328 |
Часть V. За базовыми классами |