2. Наследование
Чтобы понять, чем вызвано включение принципа наследования в концепцию объектно-ориентированного программирования, продолжим анализ программ для геометрических объектов. Опишем объект ЛИНИЯ (фрагмент 2.1).
Фрагмент 2.1 TYPE { объект-ЛИНИЯ } Line = object x,y : integer; x1,y1 : integer; Color : word; procedure Init(xc,yc,x1c,y1c: integer; cc: word); functionGetX: integer; functionGetY: integer; functionGetX1: integer; functionGetY1: integer; functionGetColor: word; procedure Show; end; {Инициализация линии } procedure Line.Init; Begin x:=xc; y:=yc; x1:=x1c; y1:=y1c; Color:=cc End; { Взять параметры линии } function Line.GetX; Begin GetX:=x; End; function Line.GetY; Begin GetY:=y; End; function Line.GetX1; Begin GetX1:=x1; End; function Line.GetY1; Begin GetY1:=y1; End; function Line.GetColor; Begin GetColor:=Color; End; { нарисовать линию } procedure Line.Show; Begin SetColor(Color); Graph.Line(x,y,x1,y1); End; |
Давайте посмотрим, чем отличается объект ЛИНИЯ от объекта ТОЧКА. С точки зрения данных у ЛИНИИ появляются два новых поля координат X1 и Y1. С точки зрения методов у ЛИНИИ добавляются методы для новых полей координат GetX1 и GetY1 и изменяются метод инициализации Init и метод рисования Show. Остальные три метода ничем не отличаются от соответствующих методов для точки. Т.е. эти методы для ЛИНИИ и для ТОЧКИ являются одинаковыми. Нельзя ли, используя данное обстоятельство, упростить описание объекта ЛИНИЯ? Принцип наследования как раз и предназначен для осуществления подобных упрощений.
Концепция наследования проста и постоянно применяется для того, чтобы описать что-то новое через уже известные понятия. Например, вводя в физике понятие “материальная точка”, мы определяем его как геометрическую точку, обладающую массой. Понятие “материальная точка” можно считать потомком понятия “геометрическая точка”, наследующим все свойства и характеристики геометрической точки и, кроме того, имеющим новый атрибут -- массу.
Наследование объектов аналогично общепринятому понятию наследования. Когда определяется новый объект как потомок уже существующего объекта, то утверждается, что потомок по большей части такой же, как и предок. К объекту-потомку в случае необходимости могут быть добавлены новые поля данных, не заменяющие уже существующие поля. В потомке могут быть добавлены новые методы и перекрыты уже существующие методы предка. Эти добавления и изменения определяют только, в чем потомок отличается от предка.
Наследование - это возможность определения нового объекта как расширения уже существующего объекта посредством сохранения полей и методов предка и описания лишь новых полей и методов. |
Объект ЛИНИЯ можно объявить потомком объекта ТОЧКА. Тогда поля Х,У и Color, а также методы GetX, GetY и GetColor можно для ЛИНИИ не описывать. Они будут наследоваться от ТОЧКИ. Для пояснения, что ЛИНИЯ -- это потомок ТОЧКИ, необходимо после слова object в круглых скобках написать название объекта-предка. ТУРБО ПАСКАЛЬ допускает у одного предка иметь множество непосредственных потомков. Однако у каждого потомка должен быть только один предок. Фрагмент 2.2 иллюстрирует описание ЛИНИИ как потомка ТОЧКИ.
Фрагмент 2.2 TYPE { объект-линия } Line = object(Point) x1,y1 : integer; procedure Init(xc,yc,x1c,y1c: integer; cc: word); functionGetX1: integer; functionGetY1: integer; procedure Show; end; { инициализация линии } procedure Line.Init; Begin Point.Init(xc,yc,cc); x1:=x1c; y1:=y1c; End; { взять параметры линии } function Line.GetX1; Begin GetX1:=x1; End; function Line.GetY1; Begin GetY1:=y1; End; { нарисовать линию } procedure Line.Show; Begin SetColor(Color); Graph.Line(x,y,x1,y1); End; |
Обратите внимание, что при инициализации параметров линии использован метод инициализации для точки. Объект-потомок совместим со своим предком, т.е. экземпляру объекта-предка можно присвоить значение экземпляра объекта-потомка:
VAR P : Point; { ТОЧКА - предок ЛИНИИ } L : Line; { ЛИНИЯ - потомок ТОЧКИ } BEGIN L.Init(100,100,200,200,Red); P:=L; END.
В этом примере инициализируется линия красного цвета с графическими координатами (100,100)-(200,200). Операция присвоения P:=L определяет все поля экземпляра объекта ТОЧКА красного цвета с координатами (100,100). Операция L:=P не будет пропущена транслятором, так как ЛИНИЯ имеет больше полей, чем ТОЧКА и при выполнении такой операции поля X1 и Y1 будут не определены.
Прямоугольник со сторонами, параллельными осям координат, принято задавать координатами левого верхнего и правого нижнего угла. Поэтому такой объект ПРЯМОУГОЛЬНИК удобно описать как потомок объекта ЛИНИЯ. Для прямоугольника не нужны новые по сравнению с линией поля данных. Необходимо изменить только метод рисования Show. Фрагмент 2.3 содержит описание объекта ПРЯМОУГОЛЬНИК как потомка объекта ЛИНИЯ.
Фрагмент 2.3 TYPE { объект-прямоугольник } Rectangle = object(Line) procedure Show; end; procedure Rectangle.Show; { нарисовать прямоугольник } Begin SetColor(Color); Graph.Rectangle(x,y,x1,y1); End; |
От объекта ТОЧКА можно получить объект ОКРУЖНОСТЬ (фрагмент 2.4):
Фрагмент 2.4 TYPE { объект - окружность } Circle = object(Point) r : integer; procedure Init(xc,yc,rc: integer; cc: word); functionGetR: integer; procedure Show; end; procedure Circle.Init; { инициализация окружности } Begin Point.Init(xc,yc,cc); r:=rc; End; function Circle.GetR; { взять параметры окружности } Begin GetR:=r; End; procedure Circle.Show; { нарисовать окружность } Begin SetColor(Color); Graph.Circle(x,y,r); End; |
Иногда возникает необходимость внутри метода данного объекта вызвать метод одного из предков этого объекта. Для этого перед именем вызываемого метода необходимо указать имя объекта, метод которого вызывается. Например, объект ПРЯМОУГОЛЬНИК С ДИАГОНАЛЯМИ можно описать фрагментом 2.5.
Фрагмент 2.5 TYPE { объект - прямоугольник с диагоналями } RectangleD = object(Rectangle) procedure Show; end; procedure RectangleD.Show; { нарисовать прямоугольник } Begin Rectangle.Show; Graph.Line(x,y,x1,y1); Graph.Line(x,y1,x1,y); End; |
П
риведенные
объекты нельзя рассматривать независимо
друг от друга. Связи между ними можно
отобразить с помощью иерархии или
дерева объектов (рис.2.1).
Применение
принципа наследования проявляются не
только в значительном сокращении
программного кода, но и в том порядке
среди различных библиотек программ,
который организуется благодаря
иерархическим родственным связям между
объектами. При этом повышение надежности
программ связано со следующими моментами:
1. Методы объектов сравнительно просты, поэтому их алгоритмы более продуманы, а значит, более надежны.
2. Разрабатывая объект, одновременно обдумывают как данные, так и методы их обработки, что повышает надежность программного обеспечения в целом.
3. Потомок использует уже проверенные и надежные методы предка. Поэтому для потомка достаточно качественно разработать его собственные методы.
4. При модификации достаточно изменить метод у одного объекта и, если данный метод наследуется, с измененным методом будут работать все объекты иерархии.
|
Контрольные вопросы |
1. В чем суть наследования? 2.Может ли данный объект иметь одного потомка? А несколько? 3.Может ли данный объект иметь несколько предков? 4.Опишите преимущества использования принципа наследования? 5.Что такое иерархическое дерево объектов?
|
Лабораторная работа №2 |
|
1. Набрать текст программы фрагмента 1.2 . Дополнить его фрагментами 2.2-2.5. Ввести экземпляры объектов Line, Rectangle, Circle и Rectangle1. Выполнить данный пример и посмотреть результат. 2. Модифицировать текст программы из задания 1, описав массивы из 25 точек, 25 линий, 25 прямоугольников и 25 окружностей. Параметры всех объектов инициализировать с использованием генератора случайных чисел. 3. Модифицировать текст программы из задания 2, использовав динамические массивы объектов. С помощью функции SizeOf определить размеры всех объектов. С помощью функции MemAvail проследить корректность выделения и освобождения динамической памяти из хиппа. 4. Разработать иерархию объектов для моделирования шахматных фигур. Написать программу для реализации данной модели. 5. Разработать иерархию управляющих элементов: кнопка, полоса скроллинга, панель кнопок. 6. Разработать иерархию диалоговых полей ввода строки, целого числа, вещественного числа, выбор строки (значения) из заданного множества.
