Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Наследование и переопределение

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

Традиционный стиль программирования допускает два решения. Во-первых, можно ввести для круга совершенно новую структуру, повторив в ней (может быть, под другими именами) те же поля X, Y и Visible и добавив новое поле Radius. Во-вторых, можно сконструировать структуру для круга, используя в ней поле с типом, ранее определенным для точки (сделать «структуру в структуре»). Оба подхода вполне приемлемы, однако ООП предлагает иной подход, который по ряду причин является гораздо более предпочтительным.

Объектно-ориентированный стиль позволяет определить новый объект как потомок другого ранее определенного типа. Это означает, что новый тип автоматически получает все поля и методы ранее введенного типа, который в этом случае называется предком или родительским типом. В этом случае в определении типа-потомка должно быть указано (в круглых скобках после служебного слова object) имя родительского типа:

type

TCircle = object (TPoint)

Radius: integer

end;

Задание родительского типа означает, что в объектовом типе TCircle неявно присутствуют все поля типа TPoint; аналогично, для переменной этого нового типа доступны все методы из TPoint:

var

OneCircle: TCircle;

begin

OneCircle.Create(100, 200);

OneCircle.Radius:= 30;

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

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

type

TRing = object (TCircle)

Radius2: integer;

end;

Тип TRing наследует поле Radius из своего непосредственного родителя TCircle, а также поля и методы из типа TPoint, который также считается (косвенным) предком для TRing.

Длина такой цепочки наследования в языке никак не ограничивается.

Вернемся к примеру с объектным типом TCircle. По правилу наследования тип TCircle имеет в своем составе методы объекта-предка TPoint. Однако, легко видеть, что если методы GetX, GetY, возвращающие текущие значения координат, вполне применимы в типе-потомке, то, например, методы SwitchOn, SwitchOff не подходят для рисования круга. Поэтому, наряду с основным полем Radius, полное описание типа TCircle должно содержать также собственные методы для рисования и удаления круга и его передвижения по экрану. Самым простым решением было бы ввести в новый тип такие методы, дав им некоторые новые имена. Но объектно-ориентированный подход позволяет определить новые методы со старыми именами, переопределив тем самым методы типа-родителя:

Type

TCircle = object (TPoint)

Radius: integer;

procedure Create (a, b, R: integer);

procedure SwitchOn;

procedure SwitchOff;

procedure Move (dx, dy: integer);

function GetR: integer;

end;

 

procedure TCircle.Create (a, b, R: integer);

begin

TPoint.Create (a, b);

Radius:= R

end;

 

procedure TCircle.SwitchOn;

begin

Visible:= true;

Graph.Circle (X, Y, Radius)

end;

 

function TCircle.GetR; integer;

begin

GetR:= Radius

end;

 

Такое определение объектного типа TCircle содержит следующие элементы:

- поля X, Y, Visible, унаследованные от родительского типа TPoint;

- собственное поле Radius;

- метод TCircle.Create, который инициализирует поля TCircle. Этот метод переопределяет внутри типа TCircle унаследованный от TPoint метод TPoint.Create. Для инициализации полей X, Y, Visible используется вызов метода TPoint.Create, который доступен (унаследован) в типе TCircle;

- методы TCircle.SwitchOn, TCircle.SwitchOff и TCircle.Move (два последних метода из экономии места не показаны), которые, соответственно, рисуют и удаляют круг и передвигают его. Эти методы полностью переопределяют (замещают) одноименные методы из TPoint, что имеет очевидный смысл: для рисования круга требуется иной алгоритм, нежели для рисования точки (в примере для этих целей используются стандартные процедуры из модуля Graph);

- новый (собственный) метод GetR для доступа к текущему значению радиуса круга;

- два унаследованных (и не переопределенных) метода GetX, GetY для получения текущих координат центра круга.

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

Рассмотрим теперь поведение объекта типа TCircle, то есть вызовы его методов. Пусть имеется следующий фрагмент программы:

var

OneCircle: TCircle;

begin

with OneCircle do

begin

Create (100, 200, 30);

SwitchOn;

Writeln (GetX, GetY)

end;

end;

Методы Create и SwitchOn определены в объекте OneCircle, поэтому их вызовы однозначно обрабатываются компилятором. Что касается методов GetX, GetY, то они не определены непосредственно в типе Circle, к которому принадлежит объект OneCircle. В таком случае компилятор, не обнаружив вызываемого метода, просматривает определение родительского типа; если данный метод и здесь не определен, то аналогично просматривается родитель родителя и т.д. Если очередной объектовый тип не имеет предка, а метод не обнаружен, то компилятор фиксирует ошибку.

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

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

OnePoint:= OneCircle;

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

 

<== предыдущая лекция | следующая лекция ==>
Объекты. Основные понятия | Виртуальные методы
Поделиться с друзьями:


Дата добавления: 2014-01-11; Просмотров: 526; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.022 сек.