Читаем С++ для "чайников" . полностью

■ Имена, которые выступают за пределы прямоугольника, ограничивающего класс, являются открытыми; к этим членам могут обращаться функции, не являющиеся членами класса или его наследников. Члены, которые находятся полностью внутри прямоугольника, недоступны снаружи класса.

■ Толстая стрелка обозначает связь типа ЯВЛЯЕТСЯ.

■ Тонкая стрелка обозначает связь типа СОДЕРЖИТ.

■■■

Автомобиль ЯВЛЯЕТСЯ транспортным средством и при этом СОДЕРЖИТ мотор.

На рис. 22.1 вы можете увидеть, что классы Checking и Savings имеют много общего. Например, оба класса включают функции-члены withdrawal( ) и deposit( ). Поскольку эти классы не идентичны, они, конечно же, должны оставаться раздельными ( в реальном банковском приложении эти два класса отличались бы гораздо существеннее ). Однако мы должны найти способ избежать дублирования.

Можно сделать так, чтобы один из этих классов наследовал другой. Класс Savings имеет больше членов, чем Checking, так что мы могли бы унаследовать Savings от Checking. Такой путь реализации этих классов приведён на рис. 22.2. Класс Savings наследует все члены класса Checking. Кроме того, в классе добавлен член noWithdrawal и переопределена функция withdrawal( ). Эта функция переопределена, поскольку правила снятия денег со сберегательного счёта отличаются от правил снятия с чекового счёта ( хотя меня эти правила вообще не касаются, поскольку у меня нет денег, которые можно было бы снять со счёта ).

Хотя наследование Savings от Checking и сберегает наш труд, нас оно не очень удовлетворяет. Главная проблема состоит в том, что оно искажает истинное положение вещей. При таком использовании наследования подразумевается, что счёт Savings является специальным случаем счёта Checking.

"Ну и что? — скажете вы. — Такое наследование работает и сохраняет нам силы и время". Это, конечно, так, но мои предупреждения — это не просто сотрясание воздуха. Такие искажения запутывают программиста уже и сейчас, но ещё больше будут мешать в дальнейшем. Однажды программист, не знакомый с нашими "приёмчиками", будет читать нашу программу, пытаясь понять, что же она делает. Вводящие в заблуждение представления очень трудны для понимания и ведения программы.

_________________

250 стр. Часть 4. Наследование

    

Рис. 22.2. Класс Savings реализован как подкласс checking

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

Такое изменение политики банка можно легко отразить в классе Checking. Все, что нужно сделать, — это добавить новый член в класс Checking, чтобы следить за минимальным балансом в течение месяца. Назовём его minimumBalance.

Однако теперь возникает проблема. Если Savings наследует Checking, значит, Savings тоже получает этот член. При этом он не используется, поскольку в сберегательных счетах минимальный баланс не нужен. Так что дополнительный член просто присутствует в классе. Итак, каждый объект чекового счёта имеет дополнительный член minimumBalance. Один дополнительный член — это не так уж и много, но он вносит свою лепту в общую неразбериху.

Такие изменения имеют свойство накапливаться. Сегодня это один член, а завтра — изменённая функция-член. В результате объекты класса Savings будут содержать множество дополнительных данных, которые нужны исключительно в классе Checking. Если вы будете невнимательны, изменения в классе Checking могут перейти к классу Savings и привести к его некорректной работе.

Далее банк решил изменить правила работы с чековыми счетами. Для этого вам требуется изменить некоторые функции в Checking. Эти изменения автоматически перейдут в подклассы. Предположим, например, что банк решил начислять дополнительные проценты по чековым вкладам ( ну, бывают же чудеса... ) — но главное чудо будет в том, что при нашей системе наследования эти же проценты будут начисляться и на сберегательных счетах.

Как же этого избежать? Если поменять местами Checking и Savings, проблема не исчезнет. Нужен некий третий класс ( назовём его Account ), который будет воплощать в себе всё то общее, что есть у Checking и Savings. Такая связь приведена на рис. 22.3.

Перейти на страницу:

Все книги серии Для чайников

Похожие книги

Разработка приложений в среде Linux. Второе издание
Разработка приложений в среде Linux. Второе издание

Книга известных профессионалов в области разработки коммерческих приложений в Linux представляет СЃРѕР±РѕР№ отличный справочник для широкого круга программистов в Linux, а также тех разработчиков на языке С, которые перешли в среду Linux из РґСЂСѓРіРёС… операционных систем. РџРѕРґСЂРѕР±но рассматриваются концепции, лежащие в основе процесса создания системных приложений, а также разнообразные доступные инструменты и библиотеки. Среди рассматриваемых в книге вопросов можно выделить анализ особенностей применения лицензий GNU, использование СЃРІРѕР±одно распространяемых компиляторов и библиотек, системное программирование для Linux, а также написание и отладка собственных переносимых библиотек. Р

Майкл К. Джонсон , Эрик В. Троан

Программирование, программы, базы данных
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript

Данная книга посвящена программированию игр с помощью ActionScript. Здесь вы найдете подробные указания, необходимые для создания самых разных игр – аркад, головоломок, загадок и даже игровых автоматов. В тексте приведены исходные коды программ и детальные, доступно изложенные инструкции. Базовые принципы программирования ActionScript рассматриваются на примере игр, однако вы без труда сможете применить полученные знания и для разработки неигровых проектов, таких как Web-дизайн и реклама. Рекомендации Гэри Розенцвейга помогут вам не только придумывать занимательные игры и размещать их на Web-сайте, но и оптимизировать скорость их работы, а также защищать свои творения от несанкционированного копирования. Представленный в книге код несложно изменить для использования в других программах.Книга предназначена для широкого круга читателей – создателей анимационных роликов, художников-оформителей, программистов и разработчиков Web-сайтов. Издание может также выступать в качестве практического пособия по изучению ActionScript.

Гэри Розенцвейг

Программирование, программы, базы данных / Программирование / Книги по IT
Язык программирования Euphoria. Справочное руководство
Язык программирования Euphoria. Справочное руководство

Euphoria (юфо'ри, также рус. эйфори'я, ра'дость) — язык программирования, созданный Робертом Крейгом (Rapid Deployment Software) в Канаде, Торонто. Название Euphoria — это акроним для «End-User Programming with Hierarchical Objects for Robust Interpreted Applications».Euphoria — интерпретируемый императивный язык высокого уровня общего назначения. C помощью транслятора из исходного кода на Euphoria может быть сгенерирован исходный код на языке Си, который в свою очередь может быть скомпилирован в исполнияемый файл или динамическую библиотеку при помощи таких компиляторов, как GCC, OpenWatcom и др. Программа Euphoria также может быть «связана» с интерпретатором для получения самостоятельного исполняемого файла. Поддерживается несколько GUI-библиотек, включая Win32lib и оберток для wxWidgets, GTK+ и IUP. Euphoria имеет встроенную простую систему баз данных и обертки для работы с другими типам баз данных.[Материал из Википедии]

Коллектив авторов

Программирование, программы, базы данных