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

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

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

Добавлен: 11.12.2025

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

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

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

}

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 )

{

/ / С о з д а н и е

б а н к о в с к о г о с ч е т а и в ы в о д а и н ф о р м а ц и и о

/ / н е м

 

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

D i r e c t D e p o s i t ( b a ,

1 0 0 ) ;

 

C o n s o l e . W r i t e L i n e ( " С ч е т

{ о } " ,

 

b a . T o B a n k A c c o u n t S t r i n g ( ) ) ;

/ / T o ж е д л я с ч е т а с н а к о п л е н и е м п р о ц е н т о в

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 ( 1 2 . 5 M ) ;

D i r e c t D e p o s i t ( s a ,

1 0 0 ) ;

 

s a . A c c u m u l a t e l n t e r e s t ( ) ;

 

C o n s o l e . W r i t e L i n e ( " С ч е т

{ о } " ,

s a . T o S a v i n g s A c c o u n t S t r i n g ( ) ) ; / / О ж и д а е м п о д т в е р ж д е н и я п о л ь з о в а т е л я

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

}

}

}

Класс B a n k A c c o u n t определяет два конструктора: один, который получает началь ное значение баланса, и конструктор по умолчанию, не получающий никаких аргуи тов. Чтобы избежать дублирования кода конструкторов, конструктор по умолчанию зывает конструктор с передаваемым начальным значением баланса посредством

вого слова

t h i s .

 

 

Класс

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 v i n g s A c c o u n t , принимающий

качестве аргументов величину процентной ставки и начальное значение баланса, перед вая в качестве последнего 0. В свою очередь, этот конструктор наиболее o6mei о вс передает начальное значение баланса соответствующему конструктору B a s e C l a s s это отражено на диаграмме на рис. 12.1).

Рис. 12.1. Передача параметров в цепочке вызовов конструкторов

П р о г р а м м а м о д и ф и ц и р о в а н а т а к и м о б р а з о м , ч т о б ы и з б е ж а т ь вызова внутренних

ф у н к ц и й I n i t . . . ( ) , з а м е н и в

их а в т о м а т и ч е с к и

в ы з ы в а е м ы м и конструкторами . Вы­

вод это й д е м о н с т р а ц и о н н о й

п р о г р а м м ы н и ч е м

не отличается от в ы в о д а ее предше

с т в е н н и ц ы .

 

 

280

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


С# предоставляет также метод, обратный конструктору и именуемый деструктором. Деструктор имеет то же имя, что и имя класса, но предваренное символом тильды (~). Например, метод - B a s e C l a s s ( ) является деструктором класса B a s e C l a s s ( ) .

С# вызывает деструктор, когда перестает использовать объект. Деструктор по умол­ чанию — единственный, который может иметь класс, поскольку деструктор не вызыва­ ется явно. Кроме того, деструктор всегда виртуален (о виртуальных методах будет рас­ сказано в главе 13, " П о л и м о р ф и з м " ) .

При использовании наследования деструкторы вызываются в порядке, обратном порядку вызова конструкторов. Таким образом, деструктор подкласса вызывается перед деструктором базового класса.

Сборка мусора и деструкторы С#

Деструктор в С# менее полезен, чем в ряде других объектно-ориентированных языков программирования, таких как С + + , поскольку в С# используется нектерминистическая деструкция. Этот термин и его важность требуют определенных

пояснений.

Память для объекта выделяется из кучи при выполнении команды n e w , например, new S u b c l a s s ( ) . Блок памяти остается зарезервированным до тех пор, пока имеет­ ся хоть одна корректная ссылка на эту память. Вы можете иметь несколько перемен­ ных, ссылающихся на один и тот же объект.

О памяти говорят, что она "недостижима", когда из области видимости выходит по­ следняя ссылка на нее. Другими словами, никто не в состоянии обратиться к блоку памяти после утраты последней ссылки на нее.

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

Обычно с б о р щ и к

м у с о р а

н е з а

м е т н о р а б о т а е т в

ф о н о в о м р е ж и м е и получает

управление тольк о

на

к о р о т к и е

п е р и о д ы в р е м е н и ,

когда н а ч и н а е т чувствоваться

нехватка памяти .

 

 

 

 

 

Деструкторы С#, такие

как

~ B a s e C l a s s ( ) , являются недетерминистическими, по­

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

/лава 12. Наследование

281


О с н о в н ой вывод — программист на С# не может полагаться на автоматический вызов деструктора, как в таком языке, как С + + , так что деструкторы в С# использую крайне редко. В С# имеются другие способы вернуть системе захваченные ресурсов которые больше не нужны, — с применением метода D i s p o s e ( ) , изучение которые увы, выходит за рамки настоящей книги.

282

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

Глава 13

Полиморфизм

>Скрывать или перекрывать методы базового класса?

>Реально ли создание абстрактных классов?

>Объявление абстрактного метода

>Создание новой иерархии поверх существующей

>Защита класса от наследования

аследование позволяет одному классу "приспособить" члены другого класса.

Таким

образом,

можно создать класс 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 . Однако

этого недостаточно

для имитации объектов реального мира.

Вернитесь к главе 12, "Наследование", если вам требуется освежить свои зна­ ния о наследовании.

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

распродаже... Хотя нет, именно последнее наверняка беспокоит вас больше всего ...

 

Для обычного потребителя отличия м и к р о в о л н о в о й печи от

о б ы ч н о й не так

важ­

ны— лишь бы они обе могли готовить л ю б и м ы е блюда, но

если взглянуть на

это

сточки зрения печи, то эти отличия становятся крайне существенны, поскольку внут­ реннее устройство печей с о в е р ш е н н о различно . М о щ ь наследования заключается втом факте, что подкласс не обязан наследовать каждый метод базового класса в том виде, в котором он написан . Подкласс может наследовать суть метода базового класса при полном отличии его реализации .

Как описывалось в главе 7, " Ф у н к ц и и ф у н к ц и й " , две или большее число функций могут иметь одинаковые имена — л и ш ь бы отличались количества и/или типы их ар­ гументов.


Простейший случай перегрузки функции

Д ве функции с одинаковым именем называются перегруженными.

Аргументы функции становятся частью ее расширенного имени (используемого в внутренне), как показано в следующем фрагменте исходного текста:

p u b l i c

c l a s s M y C l a s s

 

{

 

 

 

p u b l i c

s t a t i c

v o i d A F u n c t i o n O

 

/ / Н е к о т о р ы е д е й с т в и я

 

p u b l i c

s t a t i c

v o i d A F u n c t i o n ( i n t )

 

/ / Н е к о т о р ы е д р у г и е д е й с т в и я

 

p u b l i c

s t a t i c

v o i d A F u n c t i o n ( d o u b l e d )

/ / Н е к о т о р ы е д е й с т в и я , о т л и ч н ы е о т п е р в ы х д в у х

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 )

A F u n c t i o n ( ) ; A F u n c t i o n ( 1 ) ;

A F u n c t i o n ( 2 . 0 ) ;

}

}

C# в состоянии различать эти методы по их аргументам. Каждый из вызовов в фун| ции M a i n () обращается к своей функции.

Возвращаемый тип не является частью расширенного имени функции, так чя вы не можете иметь две функции, отличающиеся только типами возвращаемой значения.

Различные классы, различные методы

Не удивительно, что класс, которому принадлежит функция, также становится чася ее расширенного имени . Рассмотрим следующий фрагмент исходного текста:

p u b l i c

c l a s s

M y C l a s s

{

 

 

 

p u b l i c

s t a t i c

v o i d A F u n c t i o n O ;

p u b l i c

v o i d A M e t h o d ( ) ;

}

 

 

 

p u b l i c

c l a s s

U r C l a s s

{

 

 

 

p u b l i c

s t a t i c

v o i d A F u n c t i o n O ;

p u b l i c

v o i d A M e t h o d ( ) ;

}

 

 

 

p u b l i c c l a s s

P r o g r a m

284

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