Отношение обобщения.

Определение 15. Обобщение (generalization)– это отношение между более общей сущностью, называемой суперклассом(родительской или предком), и ее конкретным воплощением, называемым подклассом (дочерним или потомком).

Иногда обобщение называют отношениями типа "является", имея в виду, что одни сущности (например, круг, квадрат, треугольник) являются воплощением более общей сущности (например, класса "геометрическая фигура").

Данное отношение используется для представления иерархических взаимосвязей между различными элементами языка UML, такими как пакеты, классы, варианты использования. Применительно к диаграмме классов данное отношение описывает иерархическое строение классов и наследование их свойств и поведения.

Определение 16. Наследование (inheritance) – специальный концептуальный механизм, посредством которого более специальные элементы включают в себя структуру и поведение более общих элементов.

Благодаря механизму наследования класс-потомок обладает всеми свойствами и поведением класса-предка, а также имеет собственные свойства и поведение, которые могут отсутствовать у класса-предка.

Обобщение на диаграммах обозначается незакрашенной треугольной стрелкой, направленной на суперкласс (рис. 19).

Рис. 19. Обозначение отношения обобщения между классами.

Процедуру моделирования наследования можно проводить в следующей последовательности:

1. Найти атрибуты, операции и обязанности, общие для двух или более классов из данной совокупности. Это позволит избежать ненужного дублирования структуры и функциональности объектов.

2. Вынести эти элементы в некоторый общий суперкласс, а если такого не существует, то создать новый класс.

3. Отметить в модели, что подклассы наследуются от суперкласса, установив между ними отношение обобщения.

От одного класса-предка одновременно могут наследовать несколько классов-потомков. В этом случае на диаграмме классов для подобного отношения обобщения указывается несколько линий со стрелками. Например, класс Транспортное средство (курсив обозначает абстрактный класс) может выступать в качестве суперкласса для подклассов, соответствующих конкретным транспортным средствам, таким как: Автомобиль, Автобус, Трактор и другим. Это может быть представлено графически в форме диаграммы классов следующего вида (рис. 20).

Рис. 20. Пример графического изображения отношения обобщения для нескольких классов-потомков.

Для упрощения обозначений на диаграмме классов и уменьшения числа стрелок-треугольников и совокупности линий, обозначающих одно и то же отношение обобщения, может быть просто изображена одна стрелка, указывающая на суперкласс, начало которой разветвляется и соединяется с каждым подклассом (рис. 21).

Рис. 21. Альтернативный вариант графического изображения отношения обобщения классов для случая объединения отдельных линий.

В дополнение к стрелке обобщения может быть присоединена строка текста, указывающая на специальные свойства этого отношения в форме ограничения. Этот текст будет относиться ко всем линиям обобщения, которые идут к классам-потомкам. Т. к. свойство касается всех подклассов данного отношения, то спецификация этого свойства осуществляется в форме ограничения, которое должно быть записано в фигурных скобках.

В качестве ограничений могут быть использованы следующие ключевые слова языка UML:

·{complete} – означает, что в данном отношении обобщения специфицированы все классы-потомки, и других классов-потомков у данного класса-предка быть не может.

·{incomplete} – означает случай, противоположный первому. А именно, предполагается, что на диаграмме указаны не все классы-потомки. В последующем возможно разработчик восполнит их перечень, не изменяя уже построенную диаграмму.

·{disjoint} – означает, что классы-потомки не могут содержать объектов, одновременно являющихся экземплярами двух или более классов.

·{overlapping} – случай, противоположный предыдущему. А именно, предполагается, что отдельные экземпляры классов-потомков могут принадлежать одновременно нескольким классам.

С учетом дополнительного использования стандартного ограничения диаграмма классов, изображенная на рисунке 21, может быть уточнена (рис. 22).

Рис. 22. Вариант уточненного графического изображения отношения обобщения классов с использованием строки-ограничения.

Рассмотрим пример, иллюстрирующий процедуру моделирования наследования (рис. 23).

Рис. 23.

На первый взгляд, кажется странным, что класс "точка" не имеет никаких атрибутов, а круг имеет только радиус. С прямоугольником, вроде бы, все понятно - ширина и высота, но вот только где он расположен в пространстве, этот прямоугольник? Давайте попробуем следовать процедуре моделирования наследования. Итак, положение всех трех фигур можно однозначно определить с помощью пары чисел. Для точки - это вообще единственные ее характеристики, для круга и прямоугольника - их центры (под центром прямоугольника мы понимаем точку пересечения его диагоналей). Вот они, общие атрибуты! Таким образом, мы создали суперкласс "Фигура", имеющий два атрибута - координаты центра. Все остальные классы на этой диаграмме связаны с классом "Фигура" отношением обобщения, т. е. в них нужно доопределить только "недостающие" атрибуты - радиус, ширину и высоту. Атрибуты, описывающие координаты центра, эти классы имеют изначально как потомки класса "Фигура" - они их наследуют. Заметим, что операции классов мы тут не рассматриваем: понятно, что с ними была бы та же история.

Классы-потомки ведь наследуют атрибуты и операции суперкласса? Таким образом, они могут наследовать и их интерфейсы - то есть объекты абсолютно разной природы могут иметь один и тот же интерфейс! Так как же тогда определить, какого же все-таки класса объект?

Действительно, объекты разной природы (или говоря проще, разных классов) могут поддерживать один и тот же интерфейс именно так, как того ожидает пользователь. Примером тому может служить рассмотренная выше диаграмма с геометрическими фигурами. Все рассмотренные фигуры имеют, например, операцию рисования на экране. С точки зрения пользователя в каждом случае это одно и то же действие. Однако реализованы эти операции по-разному - ведь процедура изображения прямоугольника сильно отличается от подобной процедуры для круга. Но для пользователя это неважно: ведь сигнатура-то одна и та же! А возможно это благодаря одному из основных принципов ООП - полиморфизму. Как мы только что упомянули, работа механизма полиморфизма основана на совпадении сигнатуры метода, объявленного в интерфейсе, и сигнатуры самого метода. Методы внутри классов-потомков могут быть (и наверняка будут!) переопределены, их реализации будут различными, а сигнатуры останутся неизменными. Таким образом (и в этом легко ощутить мощь ООП), выполняя одни и те же операции, разные объекты могут вести себя по-разному.

Полиморфизм является основой для реализации механизма интерфейсов в языках программирования. Вот, кстати, и ответ на вопрос, какого класса объект: как только пользователь обращается к некоторой операции через интерфейс, определяется фактический класс объекта и вызывается соответствующая операция класса. Примеры полиморфизма можно увидеть в самых обыденных вещах, которыми мы пользуемся в повседневной жизни. Например, всем привычная кредитная карточка, является интерфейсом для доступа к банковскому счету через банкомат (и не только), одинаково работает в любой стране, вот только ведет себя чуть-чуть по-разному, т. к. банкомат выдает деньги в местной валюте.