ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 3265

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

/ / A b s t r a c t B a s e C l a s s

 

p u b l i c c l a s s S u b C l a s s l

: A b s t r a c t B a s e C l a s s

{

 

o v e r r i d e p u b l i c v o i d

O u t p u t ( s t r i n g s S o u r c e )

{

s t r i n g s = s S o u r c e . T o U p p e r ( ) ;

C o n s o l e . W r i t e L i n e ( " В ы з о в S u b C l a s s l . O u t p u t ( ) и з { о } " ,

s ) ;

}

}

/ / S u b C l a s s 2 - е щ е о д н а к о н к р е т н а я р е а л и з а ц и я к л а с с а / / A b s t r a c t B a s e C l a s s

p u b l i c c l a s s S u b C l a s s 2 : A b s t r a c t B a s e C l a s s

{

o v e r r i d e p u b l i c v o i d O u t p u t ( s t r i n g s S o u r c e )

{

s t r i n g s = s S o u r c e . T o L o w e r ( ) ;

C o n s o l e . W r i t e L i n e ( " В ы з о в S u b C l a s s 2 . O u t p u t ( ) и з { 0 } " , c l a s s P r o g r a m

s ) ;

{

p u b l i c s t a t i c v o i d T e s t ( A b s t r a c t B a s e C l a s s b a )

{

b a . O u t p u t ( " T e 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 [ ] s t r i n g s )

{

/ / Н е л ь з я с о з д а т ь о б ъ е к т к л а с с а A b s t r a c t B a s e C l a s s , / / п о с к о л ь к у о н — а б с т р а к т н ы й . Е с л и в ы с н и м е т е

/ / к о м м е н т а р и й с о с л е д у ю щ е й с т р о к и , т о С # с г е н е р и р у е т / / с о о б щ е н и е о б о ш и б к е к о м п и л я ц и и

/ / A b s t r a c t B a s e C l a s s b a = n e w A b s t r a c t B a s e C l a s s ( ) ;

/ / Т е п е р ь п о в т о р и м н а ш э к с п е р и м е н т с к л а с с о м S u b c l a s s l C o n s o l e . W r i t e L i n e ( " С о з д а н и е о б ъ е к т а S u b C l a s s l " ) ;

S u b C l a s s l

s c l = n e w S u b C l a s s l ( ) ;

 

T e s t ( s c l )

;

 

 

/ / и к л а с с о м S u b c l a s s 2

 

 

C o n s o l e . W r i t e L i n e ( " \ п С о з д а н и е

о б ъ е к т а S u b C l a s s 2 " ) ;

S u b C l a s s 2 s c 2 = n e w S u b C l a s s 2 ( ) ;

 

T e s t ( 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 ( ) ;

 

 

В программе сначала определяется класс A b s t r a c t B a s e C l a s s

с единственным аб­

страктным

методом

O u t p u t ( ) . Поскольку

о н объявлен как

a b s t r a c t , метод

Output ()

не имеет реализации, т.е. тела метода.

 

Глава 13. Полиморфизм

303


Класс A b s t r a c t B a s e C l a s s наследуют два подкласса: S u b C l a s s l и SubClass2 Оба — конкретные классы, так как перекрывают метод O u t p u t () "настоящими" мето дами и не содержат собственных абстрактных методов.

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

Методы O u t p u t () двух рассматриваемых подклассов немного различны — один из них преобразует передаваемую ему строку в верхний регистр, другой — в нижний. Вы вод программы демонстрирует полиморфную природу класса A b s t r a c t B a s e C l a s s .

С о з д а н и е о б ъ е к т а S u b C l a s s l

В ы з о в S u b C l a s s l . O u t p u t ( )

и з TEST

С о з д а н и е о б ъ е к т а S u b C l a s s 2

В ы з о в S u b C l a s s 2 . O u t p u t ( )

и з t e s t

Н а ж м и т е < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . .

Абстрактный метод автоматически является виртуальным, так что добавлять

ключевое слово v i r t u a l

к ключевому слову a b s t r a c t н е требуется.

Создание абстрактных объектов невозможно

Обратите внимание еще на одну вещь в рассматриваемой демонстрационной про-

грамме: нельзя

создавать объект A b s t r a c t B a s e C l a s s ,

но аргумент функции Test()

объявлен как

объект класса A b s t r a c t B a s e C l a s s

или

одного

из его

подклассов. Это

дополнение

крайне важно. Объекты S u b C l a s s l и

S u b C l a s s 2

могут

быть переданы

в функцию,

поскольку оба являются конкретными подклассами A b s t r a c t B a s e C l a s s ,

Здесь использовано отношение Я В Л Я Е Т С Я . Это очень мощная методика, позволяющая писать высоко обобщенные методы.

Для создания новой иерархии наследования можно также использовать ключевое слово v i r t u a l . Рассмотрим иерархию классов, показанную в приве­ денной далее демонстрационной программе I n h e r i t a n c e T e s t .

/ / I n h e r i t a n c e T e s t

- п р и м е р и с п о л ь з о в а н и я к л ю ч е в о г о с л о в а

/ / v i r t u a l д л я с о з д а н и я н о в о й и е р а р х и и к л а с с о в

n a m e s p a c e I n h e r i t a n c e T e s t

 

{

 

 

u s i n g .

S y s t e m ;

 

p u b l i c

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 )

{

 

 

C o n s o l e . W r i t e L i n e ( " \ п П е р е д а ч а

B a n k A c c o u n t " )

B a n k A c c o u n t b a = n e w B a n k A c c o u n t ( ) ;

304

Часть IV. Объектно-ориентированное программирование


T e s t l ( b a ) ;

C o n s o l e . W r i t e L i n e ( " \ п П е р е д а ч а S a v i n g s A c c o u n t " ) ; S a v i n g s A c c o u n t s a = n e w S a v i n g s A c c o u n t ( ) ;

T e s t l ( s a )

;

T e s t 2 ( s a )

;

C o n s o l e . W r i t e L i n e ( " \ п П е р е д а ч а S p e c i a l S a l e A c c o u n t s s a = n e w T e s t l ( s s a ) ;

T e s t 2 ( s s a ) ; T e s t 3 ( s s a ) ;

C o n s o l e . W r i t e L i n e ( " \ п П е р е д а ч а S a l e S p e c i a l C u s t o m e r s s c = n e w T e s t l ( s s c ) ;

T e s t 2 ( s s c ) T e s t 3 ( s s c ) ; T e s t 4 ( s s c ) ;

S p e c i a l S a l e A c c o u n t " ) ; S p e c i a l S a l e A c c o u n t ( ) ;

S a l e S p e c i a l C u s t o m e r " ) ; S a l e S p e c i a l C u s t o m e r ( ) ;

/ / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я

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 ( ) ;

p u b l i c

s t a t i c v o i d T e s t l ( B a n k A c c o u n t a c c o u n t )

C o n s o l e . W r i t e L i n e ( " \ t B T e s t ( B a n k A c c o u n t ) " ) ;

a c c o u n t . W i t h d r a w ( 1 0 0 ) ;

p u b l i c

s t a t i c v o i d T e s t 2 ( S a v i n g s A c c o u n t a c c o u n t )

C o n s o l e . W r i t e L i n e ( " \ t B T e s t ( S a v i n g s A c c o u n t ) , " ) ;

a c c o u n t . W i t h d r a w ( 1 0 0 ) ;

p u b l i c

s t a t i c v o i d T e s t 3 ( S p e c i a l S a l e A c c o u n t a c c o u n t )

C o n s o l e . W r i t e L i n e ( " \ t B T e s t ( S p e c i a l S a l e A c c o u n t ) " ) ;

a c c o u n t . W i t h d r a w ( 1 0 0 ) ;

p u b l i c

s t a t i c v o i d T e s t 4 ( S a l e S p e c i a l C u s t o m e r a c c o u n t )

C o n s o l e . W r i t e L i n e ( " \ t B T e s t ( S a l e S p e c i a l C u s t o m e r ) " ) ;

a c c o u n t . W i t h d r a w ( 1 0 0 ) ;

/ / B a n k A c c o u n t - м о д е л и р у е т б а н к о в с к и й с ч е т с н о м е р о м ,

/ / п р и с в а и в а е м ы м п р и с о з д а н и и , и б а л а н с о м

public c l a s s B a n k A c c o u n t

taa 13. Полиморфизм

305


/ / W i t h d r a w a l - в ы м о ж е т е с н я т ь с о с ч е т а л ю б у ю с у м м у , н е

/ / превышающу ю

б а л а н с . В о з в р а щ а е т р е а л ь н о

с н я т у ю с о

/ / с ч е т а с у м м у

 

 

 

 

 

v i r t u a l p u b l i c

v o i d W i t h d r a w ( d e c i m a l

d W i t h d r a w )

{

 

 

 

 

 

C o n s o l e . W r i t e L i n e ( " \ Ь \ Ь в ы з ы в а е т " • +

 

 

 

 

" B a n k A c c o u n t . W i t h d r a w ()

11) ;

}

 

 

 

 

 

}

 

 

 

 

 

/ / S a v i n g s A c c o u n t - б а н к о в с к и й с ч е т с н а ч и с л е н и е м

/ / п р о ц е н т о в

 

 

 

 

 

p u b l i c c l a s s S a v i n g s A c c o u n t : B a n k A c c o u n t

 

{

 

 

 

 

 

o v e r r i d e p u b l i c v o i d W i t h d r a w ( d e c i m a l

m W i t h d r a w a l )

{

 

 

 

 

 

C o n s o l e . W r i t e L i n e ( " \ t \ t B b i 3 b i B a e T " +

 

 

 

 

 

 

 

 

" S a v i n g s A c c o u n t . W i t h d r a w ( ) " ) ;

}

 

 

 

 

 

}

/ / S p e c i a l S a l e A c c o u n t - с ч е т и с п о л ь з у е т с я т о л ь к о д л я / / п р о д а ж

p u b l i c c l a s s

S p e c i a l S a l e A c c o u n t : S a v i n g s A c c o u n t

{

 

n e w virtual

p u b l i c v o i d W i t h d r a w ( d e c i m a l m W i t h d r a w a l )

{

 

C o n s o l e . W r i t e L i n e ( " \ t \ T B B I 3 B M A E T " +

 

" S p e c i a l S a l e A c c o u n t . W i t h d r a w ( ) " ) ;

}

 

}

/ / S a l e S p e c i a l C u s t o m e r - с ч е т т о л ь к о д л я с п е ц и а л ь н ы х / / п о к у п а т е л е й

p u b l i c c l a s s S a l e S p e c i a l C u s t o m e r : S p e c i a l S a l e A c c o u n t

{

o v e r r i d e p u b l i c v o i d W i t h d r a w ( d e c i m a l m W i t h d r a w a l )

{

C o n s o l e . W r i t e L i n e ( " \ t \ T B B I 3 B I B A E T " +

" S a l e S p e c i a l C u s t o m e r . W i t h d r a w ( ) " ) ;

}

}

}

Каждый из указанных классов расширяет наследуемый класс. Заметьте, однако, что метод S p e c i a l S a l e A c c o u n t . W i t h d r a w ( ) помечен как v i r t u a l , что разрывай цепь наследования в этой точке. При рассмотрении с точки зрения B a n k A c c o u n t клас-

сы S p e c i a l S a l e A c c o u n t и

S a l e S p e c i a l C u s t o m e r

выглядят в точности как Sav-

i n g s A c c o u n t . И только при

рассмотрении с точки

зрения S p e c i a l S a l e A c c o u n t

становятся доступны новые версии W i t h d r a w ( ) .

 

Все это показано в приведенной демонстрационной программе . Функция Main() вызывает ряд методов T e s t ( ) , каждый из которых разработан для своего подкласса,]

306

Часть IV. Объектно-ориентированное программировать


Каждая из

версий метода T e s t О вызывает W i t h d r a w () с точки зрения различного

класса объекта.

Вывод программы имеет следующий вид:

Передача

B a n k A c c o u n t

вT e s t ( B a n k A c c o u n t )

вы з ы в а е т B a n k A c c o u n t . W i t h d r a w ( )

1ередача

S a v i n g s A c c o u n t

вT e s t ( B a n k A c c o u n t )

вы з ы в а е т S a v i n g s A c c o u n t . W i t h d r a w ( )

вT e s t ( S a v i n g s A c c o u n t )

вы з ы в а е т S a v i n g s A c c o u n t . W i t h d r a w ( )

Передача

S p e c i a l S a l e A c c o u n t

в Test(BankAccount)

вызывает SavingsAccount.Withdraw()

вT e s t ( S a v i n g s A c c o u n t )

вы з ы в а е т S a v i n g s A c c o u n t . W i t h d r a w ( )

вTest(SpecialSaleAccount)

вызывает SpecialSaleAccount.Withdraw()

Передача

S a l e S p e c i a l C u s t o m e r

вT e s t ( B a n k A c c o u n t )

вы з ы в а е т S a v i n g s A c c o u n t . W i t h d r a w ( )

вTest(SavingsAccount)

вызывает SavingsAccount.Withdraw() в Test(SpecialSaleAccount)

вызывает SaleSpecialCustomer.Withdraw()

вT e s t ( S a l e S p e c i a l C u s t o m e r )

в ы з ы в а е т

S a l e S p e c i a l C u s t o m e r . W i t h d r a w ( )

Нажмите < E n t e r >

д л я з а в е р ш е н и я п р о г р а м м ы . . .

Полужирным ш р и ф т о м выделены строки, представляющие особый интерес. Классы

BankAccount и S a v i n g s A c c o u n t работают в точности так, как и

ожидалось. Однако

при вызове

T e s t ( S a v i n g s A c c o u n t ) и S p e c i a l S a l e A c c o u n t ,

и S a l e S p e c i a l ­

Customer

передаются

как

S a v i n g s A c c o u n t . В то

же время

S a l e S p e c i a l C u s ­

tomer при

передаче в

T e s t

( S p e c i a l S a l e A c c o u n t )

работает как наследник этого

пасса, т.е. фактически создается новая иерархия наследования.

Создание новой иерархии

Зачем С# поддерживает создание новой иерархии наследования? Неужели обычного полиморфизма недостаточно?

С# формировался как "сетевой" язык в том смысле, что классы при работе програм­ мы—и даже подклассы — могут быть распределены по сети Интернет. То есть про­ грамма, которую вы пишете, м о ж е т непосредственно использовать классы из стан­ дартных хранилищ, расположенных на других компьютерах в Интернете.

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

Глава 13. Полиморфизм

307