Упражнения
1. Обоснуйте утверждение: если не используется ни замещение, ни уточнение,
то подкласс всегда должен быть подтипом.
2. Приведите пример, иллюстрирующий, что если имеет место семантика
замещения, то подкласс не обязан быть подтипом.
3. Хотя систематическое использование семантики уточнения делает более
сложным создание подклассов, не являющихся подтипами, такое все же
возможно. Проиллюстрируйте это, приведя пример уточняющего подкласса,
не являющегося тем не менее подтипом базового класса.
4. Часто во время инициализации экземпляра подкласса должны быть
выполнены по очереди: некоторый код родительского класса, код дочернего
класса, затем снова код родительского класса. Например, для оконных
систем родительский класс выделяет память для важных структур данных,
затем дочерний класс модифицирует некоторые поля этих структур (такие,
как имя и размер окна), и наконец родительский класс отображает окно на
экране дисплея. Как данная последовательность вызовов может быть
выполнена в объектно-ориентированном языке программирования?
Подсказка: вероятно, вам придется разбить процесс инициализации на два
сообщения.
5. Не всегда семантика уточнения легко моделируется семантикой замещения.
Чтобы продемонстрировать это, напишите набор классов, обеспечивающих
выполнение действий, напоминающих подпрограммы создания тэгов
WWW-адресов, описанные в разделе 11.4.1. Как и в случае упражнения 4,
вам, возможно, понадобится ввести ряд «скрытых» методов.
Глава 12: Следствия наследования
Наследование оказывает большое влияние практически на все аспекты языка
программирования. В этой главе мы исследуем некоторые следствия, вытекающие из
реализации наследования, рассматривая систему типов данных, смысл операторов (типа
оператора присваивания), проверку равенства объектов, выделение памяти.
Мы уже описали отношение «быть экземпляром» как фундаментальное свойство
наследования. Одна из точек зрения на отношение «быть экземпляром» — это
рассматривать его как средство, связывающее тип данных (в смысле типа переменной) и
набор значений (а именно значения, которые могут законным образом содержаться в
переменной). Если переменная win описана как экземпляр конкретного класса, скажем
Window, то конечно же она может содержать значения типа Window. Если мы имеем
подкласс класса Window, например TextWindow, то, поскольку TextWindow «является
экземпляром» Window, имеет смысл присвоить переменной win значение типа
TextWindow. Это называется принципом подстановки, который мы встречали в
предыдущих главах.
В то время как сам принцип имеет интуитивно понятный смысл, с практической точки
зрения наличествуют трудности реализации объектно-ориентированных языков таким
образом, чтобы это интуитивное поведение могло быть реализовано. Такие трудности не
являются непреодолимыми, но способ их решения различается в разных языках.
Исследование этих проблем, а также то, как они влияют на язык программирования,
выявляет скрытые свойства языка, которые с большой вероятностью доставляют
неприятности неосторожным программистам.
PDF created with pdfFactory Pro trial version www.pdffactory.com