Основы объектно-ориентированного программирования
0e1cc9b4

Прямоугольники


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

Преимущества такой смеси общих и специфических компонентов можно использовать, определив класс RECTANGLE как наследника (heir) класса POLYGON. При этом все компоненты класса POLYGON, называемого родителем (parent) класса RECTANGLE, по умолчанию будут применимы и к классу-наследнику. Для этого достаточно включить в RECTANGLE предложение наследования (inheritance clause):

class RECTANGLE inherit POLYGON feature ... Компоненты, специфичные для прямоугольников ... end

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

Вторая возможность полезна для такого компонента, который уже имелся у родителя, но у наследника должен быть описан в другом виде. Рассмотрим периметр perimeter. Для прямоугольников его можно вычислить более эффективно: не нужно вычислять четыре длины сторон, достаточно удвоить сумму длин двух сторон. Наследник, переопределяющий некоторый компонент родителя, должен объявить об этом в предложении наследования, включив предложение redefine:

class RECTANGLE inherit POLYGON redefine perimeter end feature ... end

Это позволяет включить в предложение feature класса RECTANGLE новую версию компонента perimeter, которая заменит его версию из класса POLYGON.
Если не включить объявление redefine, то новое объявление компонента perimeter среди других компонентов класса RECTANGLE приведет к ошибке, поскольку у RECTANGLE уже есть компонент perimeter, унаследованный от POLYGON, т.е. у некоторого компонента окажется два определения.

Класс RECTANGLE выглядит следующим образом:

indexing description: "Прямоугольники, - специальный случай многоугольников" class RECTANGLE inherit POLYGON redefine perimeter end creation make feature -- Инициализация make (center: POINT; s1, s2, angle: REAL) is -- Установить центр прямоугольника в center, длины сторон -- s1 и s2 и ориентацию angle. do ... end feature -- Access side1, side2: REAL -- Длины двух сторон diagonal: REAL -- Длина диагонали perimeter: REAL is -- Сумма длин сторон -- (Переопределение версии из POLYGON) do Result := 2 S (side1 + side2) end invariant four_sides: count = 4

first_side: (vertices.i_th (1)).distance (vertices.i_th (2)) = side1 second_side: (vertices.i_th (2)).distance (vertices.i_th (3)) = side2 third_side: (vertices.i_th (3)).distance (vertices.i_th (4)) = side1 fourth_side: (vertices.i_th (4)).distance (vertices.i_th (1)) = side2 end



Для списка i_th(i) дает элемент в позиции i ( i-й элемент, следовательно это имя запроса).
Так как RECTANGLE является наследником класса POLYGON, то все компоненты родительского класса применимы и к новому классу: vertices, rotate, translate, perimeter (в переопределенном виде) и все остальные. Их не нужно повторять в определении нового класса.

Этот процесс транзитивен: всякий класс, будучи наследником RECTANGLE, например, SQUARE, также обладает всеми компонентами класса POLYGON.


Содержание раздела