Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GoslingJava2.doc
Скачиваний:
139
Добавлен:
23.02.2016
Размер:
2.39 Mб
Скачать

3.9. Расширение классов: когда и как

Возможность создания расширенных классов— одно из главных достоинств объектно-ориентированного программирования. Когда вы расширяете класс, чтобы наделить его новыми функциями, то при этом возникает так называемое отношение подобия (IsA relationship)— расширение создает новый тип объектов, которые “подобны” исходному классу. Отношение подобия существенно отличается от отношения принадлежности (HasA relationship), при котором один объект пользуется другим для хранения информации о своем состоянии или для выполнения своих функций— ему “принадлежит” ссылка на данный объект.

Давайте рассмотрим пример. Допустим, у нас имеется класс Point, представляющий точку в двумерном пространстве в виде пары координат (x, y). Класс Point можно расширить и создать на его основе класс Pixel для представления цветного пикселя на экране. Pixel “подобен” Point; все, что справедливо по отношению к простой точке, будет справедливо и по отношению к пикселю. В класс Pixel можно включить механизм для хранения информации о цвете пикселя или ссылку на объект-экран, на котором находится пиксель. Пиксель “подобен” точке (то есть является ее частным случаем), таккак он представляет собой точку на плоскости (экране) с расширенным контрактом (для него также определено понятие цвета и экрана).

С другой стороны, круг нельзя считать частным случаем точки. Хотя в принципе круг можно описать как точку, имеющую радиус, он обладает рядом свойств, которые отсутствуют у точки. Например, если у вас имеется метод, который помещает центр некоторого прямоугольника в заданной точке, то какой смысл будет иметь этот метод для круга? Каждому кругу “принадлежит” центр, который является точкой, но круг не является точкой с радиусом и не должен представляться в виде подкласса Point.

Правильный выбор иногда оказывается неочевидным— в зависимости от конкретного приложения могут применяться различные варианты. Единственное требование заключается в том, чтобы приложение работало, и притом осмысленно.

Налаживание связей подобия и принадлежности— задача нетривиальная и чреватая осложнениями. Например, при использовании объектно-ориентированных средств для проектировании базы данных о работниках фирмы можно пойти по наиболее очевидному и общепринятому пути— создать класс Employee, в котором хранятся общие сведения для всех работников (например, имя и табельный номер) и затем расширить его для работы с определенными категориями работников— Manager, Engineer, FileClerk и т.д.

Такой вариант не подходит в реальной ситуации, когда одно и то же лицо выполняет несколько функций. Скажем, инженер может одновременно являться менеджером группы и, следовательно, присутствует сразу в двух качествах. Возьмем другой пример— аспирант может являться и учащимся, и преподавателем.

Более гибкий подход состоит в том, чтобы создать класс Role (функция работника) и расширить его для создания специализированных классов— например, Manager. В этом случае можно изменить класс Employee и превратить его в набор объектов Role. Тогда конкретное лицо может быть связано с постоянно изменяющимся набором функций внутри организации. От концепции “менеджер является работником” мы переходим к концепции “менеджер является функцией”, при которой работнику может принадлежать функция менеджера наряду с другими функциями.

Неправильный выбор исходной концепции затрудняет внесение изменений в готовую систему, поскольку они требуют значительных переделок в текстах программ. Например, в методах, реализованных с учетом первой концепции базы данных работников, несомненно будет использоваться тот факт, что объект Manager может применяться в качестве объекта Employee. Если переключиться на вторую концепцию, то это утверждение станет ложным, и все исходные программы перестанут работать.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]