Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
251.9 Кб
Скачать

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. Разработать иерархию диалоговых полей ввода строки, целого числа, вещественного числа, выбор строки (значения) из заданного множества.