ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.12.2025
Просмотров: 3281
Скачиваний: 1
Б а л а н с B a n k A c c o u n t р а в е н |
$ 1 0 0 . 0 0 |
|
|
|
|
|
|
|||||||
Б а л а н с S a v i n g s A c c o u n t |
р а в е н |
$ 1 0 0 . 0 0 |
|
|
|
|
|
|||||||
Н а ж м и т е < E n t e r > д л я з а в е р ш е н и я п р о г р а м м ы . . . |
|
|
|
|
||||||||||
В этот раз, вместо снятия со |
счета |
в |
функции |
M a i n ( ) , программа передает объект |
||||||||||
счета функции M a k e A W i t h d r a w a l ( ) . |
|
|
|
|
|
|
|
|
||||||
Первый вопрос очевиден: как функция |
M a k e A W i t h d r a w a l () |
может |
принимать |
|||||||||||
объект |
S a v i n g s A c c o u n t , |
|
если |
она ожидает в качестве аргумента объект BankAc |
||||||||||
c o u n t ? Ответ не |
менее |
ясен: |
потому |
что |
S a v i n g s A c c o u n t |
Я В Л Я Е Т С Я |
BankAc |
|||||||
c o u n t |
(см. главу 12, "Наследование") . |
|
|
|
|
|
|
|
|
|||||
Второй вопрос |
не |
так |
очевиден. Когда функции M a k e A W i t h d r a w a l |
() |
передает! |
|||||||||
объект |
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 () |
— это |
понятно. Не |
|||||||||
когда передается объект типа S a v i n g s A c c o u n t , |
вызывается тот |
же метод. Должен ли |
||||||||||||
в этом |
случае вызываться метод W i t h d r a w () |
подкласса? |
|
|
|
|
||||||||
С |
одной стороны, |
поскольку |
объект |
ba |
принадлежит типу |
B a n k A c c o u n t , вызов |
||||||||
b a . W i t h d r a w () |
должен вызывать метод B a n k A c c o u n t . W i t h d r a w ( ) . |
С другой сто |
||||||||||||
роны, |
хотя объект ba и объявлен |
как 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 , |
так |
что |
|
должен |
быть вызван |
метод |
S a v i n g s A c |
||||||
c o u n t |
. W i t h d r a w ( ) . Оба |
аргумента достаточно |
логичны . |
|
|
|
|
|||||||
В данном случае С# принимает как более весомый первый аргумент. Это более безопасный выбор — работать с объявленным типом — поскольку он устраняет все недора зумения. Объект объявлен как 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 , который хранится в переменной типа B a n k A c c o u n t . Такая
возможность принятия |
решения во время выполнения программы называется полимор |
|
физмом, или поздним связыванием (late binding). Стратегия использования |
объявленного |
|
типа называется ранним |
связыванием (early binding), в противоположность |
позднему. |
Термин полиморфизм происходит из греческого языка: поли означает много,
аморф — форма, или действие.
По л и м о р ф и з м и позднее связывание вообще-то не одно и то же. Однако их отличие весьма тонкое. Полиморфизм означает возможность принятия решения о том, какой ме
тод должен быть вызван в процессе выполнения программы . Позднее связывание — спо соб реализации полиморфизма языком программирования .
П о л и м о р ф и з м является ключевой составляющей частью объектно-ориентированного программирования . Он настолько важен, что языки, его не поддерживающие, не имеют права называться объектно-ориентированными.
Я з ы к и программирования, поддерживающие классы, но не поддерживающие полиморфизм, называются объектно-основанными языками (object-based lan guages). Примером такого языка может служить язык Ada.
292 |
Часть IV. Объектно-ориентированное программирование |
Без полиморфизма в наследовании мало толку. Позвольте привести наглядный при мер, иллюстрирующий данный тезис. Предположим, вы написали м о щ н у ю программу, использующую класс... ну, скажем, S t u d e n t . После нескольких месяцев проектирова ния, кодирования и тестирования вы наконец-то вынесли ее на суд восхищенных пользо вателей (начинающих даже поговаривать, что совершенно напрасно не существует Но - бевской премии в области программирования) .
Проходит время, и ваш шеф требует, чтобы вы добавили в программу возможность рабо ты с аспирантами, которые, конечно, похожи на студентов, но все же немного отличаются от них (сами аспиранты считают, что они отличаются во всем). Предположим, что формулы для вычисления оплаты за обучение для студентов и аспирантов совершенно различны. Вашему боссу это безразлично, но в программе имеется масса вызовов функции C a l c T u i t i o n ( ) , яредаазначенной для таких расчетов. Вот пример одного из таких вызовов:
v o i d S o m e F u n c t i o n ( S t u d e n t s )
{
// . . . К а к и е - т о д е й с т в и я . . .
s . C a l c T u i t i o n ( ) ; II... продолжение . . .
}
Если бы С# не поддерживал позднее связывание, то вам бы пришлось редактировать функцию S o m e F u n c t i o n ( ) , чтобы проверять в ней, является ли переданный объект s пе
ременной типа S t u d e n t или |
G r a d u a t e S t u d e n t . Программа должна была |
бы вызывать |
Student. C a l c T u i t i o n () |
в случае, когда переменная s принадлежала бы |
классу S t u - |
|dent, и G r a d u a t e S t u d e n t . C a l c T u i t i o n () в случае класса G r a d u a t e S t u d e n t . Это было бы не так страшно, если бы не две вещи.
Это только одна функция. А теперь представьте, что C a l c T u i t i o n () вызывает
ся в сотнях мест...
Предположим, что C a l c T u i t i o n () — не единственное отличие между двумя классами. Ш а н с ы , что вы найдете все места в программе, требующие изменений, резко снижаются ...
При поддержке полиморфизма вы просто позволяете С# самостоятельно решить, ка кой метод должен быть вызван.
Использование is для полиморфного доступа к скрытому методу
Каким образом сделать программу полиморфной? Один из подходов для решения
этой задачи в |
С# состоит в использовании ключевого слова i s (о котором |
рассказыва |
||||
юсь в |
главе |
12, "Наследование") . Выражение ba |
is |
S a v i n g s A c c o u n t |
возвращает |
|
иачение |
t r u e |
или f a l s e в зависимости от класса |
объекта во время выполнения |
про |
||
граммы. Объявленный тип может быть B a n k A c c o u n t , |
но с какого типа объектом |
при |
||||
ходится иметь дело в реальности? В приведенном далее фрагменте исходного текста is
используется для |
обращения |
к функции W i t h d r a w () класса |
S a v i n g s A c c o u n t . |
|
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 k e A W i t h d r a w a l ( B a n k A c c o u n t b a , |
||
|
|
|
d e c i m a l |
m A m o u n t ) |
Глава 13. |
Полиморфизм |
|
293 |
|