Бертран Мейер - Основы объектно-ориентированного программирования
- Название:Основы объектно-ориентированного программирования
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Бертран Мейер - Основы объектно-ориентированного программирования краткое содержание
Фундаментальный учебник по основам объектно-ориентированного программирования и инженерии программ. В книге подробно излагаются основные понятия объектной технологии – классы, объекты, управление памятью, типизация, наследование, универсализация. Большое внимание уделяется проектированию по контракту и обработке исключений, как механизмам, обеспечивающим корректность и устойчивость программных систем.
В книге Бертрана Мейера рассматриваются основы объектно-ориентированного программирования. Изложение начинается с рассмотрения критериев качества программных систем и обоснования того, как объектная технология разработки может обеспечить требуемое качество. Основные понятия объектной технологии и соответствующая нотация появляются как результат тщательного анализа и обсуждений. Подробно рассматривается понятие класса - центральное понятие объектной технологии. Рассматривается абстрактный тип данных, лежащий в основе класса, совмещение классом роли типа данных и модуля и другие аспекты построения класса. Столь же подробно рассматриваются объекты и проблемы управления памятью. Большая часть книги уделена отношениям между классами – наследованию, универсализации и их роли в построении программных систем. Важную часть книги составляет введение понятия контракта, описание технологии проектирования по контракту, как механизма, обеспечивающего корректность создаваемых программ. Не обойдены вниманием и другие важные темы объектного программирования – скрытие информации, статическая типизация, динамическое связывание и обработка исключений. Глубина охвата рассматриваемых тем делает книгу Бертрана Мейера незаменимой для понимания основ объектного программирования.
Основы объектно-ориентированного программирования - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
У дублируемого потомка версии дублируемого компонента, наследуемые под одним и тем же именем, представляют один компонент. Версии, наследуемые под разными именами, представляют разные компоненты, являясь репликацией оригинала дублируемого предка.
Это правило, распространяясь как на атрибуты, так и на методы, дает нам мощный механизм репликации: из одного компонента класса его потомки могут получить два или более компонента. Для атрибутов оно означает введение нового поля во всех экземплярах класса, для метода - новую процедуру или функцию, изначально - с тем же алгоритмом работы.
За исключением особых случаев, включающих переопределение, репликация может носить только концептуальный характер: фактического дублирования кода не происходит, но дублируемый потомок имеет доступ к двум компонентам.
Правило придает желаемую гибкость процессу объединения классов. Вот как может выглядеть класс FRENCH_US_DRIVER :
class FRENCH_US_DRIVER inherit
FRENCH_DRIVER
rename
address as french_address,
violation_count as french_violation_count,
pay_fee as pay_french_fee
end
US_DRIVER
rename
address as us_address,
violation_count as us_violation_count,
pay_fee as pay_us_fee
end
feature
...
end
В данном случае смена имен происходит на последнем этапе - у дублируемого потомка, но полное или частичное переименование могло быть выполнено и родителями - US_DRIVER и FRENCH_DRIVER . Важно, что будет в конце, - получит ли компонент при дублируемом наследовании одно или разные имена.
Компоненты age и pass_birthday переименованы не были, а потому, как мы и хотели, они используются совместно.
Реплицируемый атрибут, скажем, address , в каждом экземпляре класса FRENCH_US_ DRIVER будет представлен несколькими полями данных. Тогда при условии, что эти классы содержат только указанные нами компоненты, их экземпляры будут выглядеть как на рис. 15.18.
Рис. 15.17. Совместное использование и репликация
Рис. 15.18. Репликация атрибутов
(Организация FRENCH_DRIVER и US_DRIVER аналогична организации DRIVER , см. рисунок.)
Особенно важным в реализации классов является умение избегать репликации совместно используемых компонентов, например age из FRENCH_US_DRIVER . Не имея достаточно опыта, можно легко допустить такую ошибку и реплицировать все поля класса. Тратить память впустую недопустимо, так как по мере спуска по иерархии "мертвое" пространство будет лишь возрастать, что приведет к катастрофически неэффективному расходованию ресурсов. (Помните, что каждый атрибут во время выполнения потенциально представлен во многих экземплярах класса и его потомков.)
Механизм компиляции, описанный в конце этой книги, на деле дает гарантию того, что потерь памяти на атрибуты не будет, - концептуально совместно используемые (shared) атрибуты класса будут располагаться в общей для них (shared) физической памяти. Это - один из сложнейших компонентов реализации наследования и вызовов при динамическом связывании. Ситуация усложняется еще и тем, что подобное дублируемое наследование не должно влиять на производительность, что означает:
[x].нулевые затраты на поддержку универсальности;
[x].низкие, ограниченные константой, затраты на динамическое связывание (не зависящие от наличия в системе дублируемого наследования классов).
Поскольку существует реализация, отвечающая этим целям, то и в любой системе техника дублируемого наследования не должна требовать значительных издержек.
Дублируемое наследование в С++ следует другому образцу. Уровень, на котором принимается решение, разделять или дублировать компоненты, - это класс. Поэтому при необходимости дублирования одного компонента, приходится дублировать все. В Java эта проблема исчезает, поскольку запрещено множественное наследование. |
Ненавязчивое дублирующее наследование
На практике не столь часто встречаются примеры, подобные "межконтинентальным" водителям, в которых нужны и репликация компонентов, и их совместное применение. Они не для новичков. Следует приобрести опыт, чтобы браться за них.
Иначе в попытке использовать дублирующее наследование "в лоб", можно лишь все усложнить, когда это и не нужно.
Рис. 15.19. Избыточное наследование
На рисунке показана типичная ошибка начинающих (или рассеянных разработчиков): класс D объявлен наследником B , ему нужны также свойства класса A , но B сам является потомком A . Забыв о транзитивности наследования, разработчик пишет:
class D ... inherit
B
A
...
В итоге возникает дублируемое наследование. Его избыточностьочевидна. Впрочем, при надлежащем соблюдении принятых соглашений все компоненты классов (при сохранении их имен) будут использоваться совместно, новых компонентов не появится, и дополнительных издержек не будет. Даже если в B часть имен атрибутов меняется, единственным следствием этого станет лишь некоторый расход памяти.
Из этого есть только одно исключение: случай, когда B переопределяет один из компонентов A , что приведет к неоднозначности в D . Но тогда, как будет показано ниже, компилятор выдаст сообщение об ошибке, предлагая выбрать в D один из двух вариантов компонента.
Избыточное, хотя и безвредное наследование может произойти, если A - это класс, реализующий универсальные функции, например ввода-вывода, необходимые B и D . В этом случае достаточно объявить D наследником B . Это автоматически делает D потомком A , что позволяет обращаться ко всем нужным функциям. Избыточное наследование не нанесет никакого вреда, оставшись практически без последствий.
Такие случаи "безвредного" наследования могут происходить при порождении от универсальных классов ANY и GENERAL , речь о которых пойдет в следующей лекции. |
Правило переименования
В этом разделе мы не введем никаких новых понятий, а лишь точнее сформулируем известные правила и приведем пример, призванный пояснить сказанное.
Начнем с запрета возникновения конфликта имен:
Определение: финальное имя
Финальным именем компонента класса является:
[x].Для непосредственного компонента (объявленного в самом классе) - имя, под которым он объявлен.
Читать дальшеИнтервал:
Закладка: