ColoredWindow. Цвет фона будет отличаться от белого за счет добавления нового поля,
содержащего цвет. Придется также переопределить наследуемую процедуру изображения
окна, в которой происходит фоновая заливка.
Порождение подкласса для обобщения часто используется в случае, когда общий проект
основывается в первую очередь на значениях данных и меньше — на функциональном
поведении. Это видно на примере с цветным окном, так как оно содержит поля данных,
необязательные в случае черно-белого окна.
Как правило, следует избегать порождения подкласса для обобщения, пользуясь
перевернутой иерархией типов и порождением для специализации. Однако это не всегда
возможно.
7.3.5. Порождение подкласса для расширения
В то время как порождение подкласса для обобщения модифицирует или расширяет
существующие функциональные возможности объекта, порождение для расширения
добавляет совершенно новые свойства. Его можно отличить по тому, что порождение для
обобщения обязано переопределить по крайней мере один метод родителя, а
функциональные возможности подкласса привязаны к родительским. Расширение просто
добавляет новые методы к родительским, и функциональные возможности подкласса
менее крепко привязаны к существующим методам родителя.
Примером порождения подкласса для расширения является множество текстовых строк
StringSet, наследующее свойства общего класса множеств Set и предназначенное для
хранения строковых величин. Такой класс мог бы предоставлять дополнительные методы
для строковых операций, например «найти по префиксу», который возвращал бы
подмножество всех элементов множества, начинающихся с определенной подстроки.
Такие операции имеют смысл для подкласса, но не для родительского класса.
Поскольку функциональные возможности родителя остаются нетронутыми и доступными,
порождение подкласса для расширения не противоречит принципу подстановки и,
следовательно, такие подклассы всегда будут подтипами.
7.3.6. Порождение подкласса для ограничения
Порождение для ограничения происходит в случае, когда возможности подкласса более
ограничены, чем в родительском классе. Так же, как и при обобщении, порождение для
ограничения чаще всего возникает, когда программист строит класс на основе
существующей иерархии, которая не должна или не может быть изменена.
Допустим, существующая библиотека классов предоставляет структуру данных Deque
(double-ended-queue, очередь с двумя концами). Элементы могут добавляться или
удаляться с любого конца структуры типа Deque, но программист желает создать класс
Stack, вводя требование добавления или удаления элементов только с одного конца стека.
Таким же образом, как и при порождении для конструирования, программист может
построить класс Stack как подкласс класса Deque и модифицировать нежелательные
методы так, чтобы они выдавали сообщение об ошибке в случае применения. Такие
методы переопределяют существующие и ограничивают их возможности, что
характеризует порождение подкласса для ограничения. (Переопределение, с помощью
PDF created with pdfFactory Pro trial version www.pdffactory.com