Студопедия

КАТЕГОРИИ:


Архитектура-(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)

Перекрытие методов




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

 

Наследование смело можно назвать краеугольным камнем объектно–ориентированного программирования. Наследование реализует механизм расширения возможностей существующих классов без изменения их исходного кода.

 

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

Базовый класс называется родительским или предком. Производный класс называется дочерним или наследником.

 

Для иллюстрации принципов наследования обратимся к объявлению класса TAirplane и создадим на его основе класс самолетов военного назначения:

 

TMilitaryPlane = class(TAirplane)

private

TheMission: TMission;

constructor Create(AName:string; AType:Integer);

function GetStatus(varStatusString:string):Integer;override;

protected

procedure TakeOff(Dir:Integer); override;

procedure Land; override;

procedure Attack; virtual;

procedure SetMission; virtual;

end;

 

Дочерний класс TMilitaryPlane имеет все чем владеет его предок плюс ряд новых ценностей. Прежде всего обратим внимание на первую строку объявления класса. Здесь в скобках записано имя родительского класса TAirplane.

 

ПРИМЕЧАНИЕ. Производный (дочерний) класс автоматически получает «в наследство» все поля и методы предка. Можно добавить новые поля и методы т.е. все то, что необходимо для придания классу новых функциональных возможностей. Удалять существующие поля и методы нельзя.

Здесь мы добавили скрытое поле – объект класса TMission. Класс TMission здесь не показан, но в него можно инкапсулировать все, что связано с понятием «боевая задача»: цель, ориентиры, пути подхода и отхода, высоты, курсы и т.д. Тем самым мы показали, что полем класса может быть объект другого (или даже этого же) класса.

 

Сначала рассмотрим механизм виртуальных методов на примере метода TakeOff. Процедура SendMessage родительского класса обращается к методу TakeOff в ответ на команду – сообщение MsgTakeOff. Если дочерний класс TMilitaryPlane не имеет собственного метода TakeOff, то унаследованная процедура SendMessage будет по–прежнему вызывать метод TakeOff родителя. Но в нашем случае класс TMilitaryPlane имеет собственный метод TakeOff, который перекрывает (override) соответствующий виртуальный метод предка. Поэтому процедура SendMessage, несмотря на то что объявлена и описана в родительском классе, будет вызывать тот метод, который фактически принадлежит дочернему классу. В данном случае это будет метод TakeOff класса TMilitaryPlane.

 

Новый термин. Замещение метода базового класса одноименным методом дочернего класса называется перекрытием метода.

 

 

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

 

ПРИМЕЧАНИЕ. В Object Pascal методы могут быть динамическими (dynamic). Динамические методы ведут себя точно также как и виртуальные. Различие между динамическими и виртуальными методами заключается в реализации их вызова. Реализация динамических методов требует меньше памяти, но больше времени.

 

Цель перекрытия методов в производных классах – либо полностью изменить алгоритм метода, либо модернизировать его. Пусть, например, мы хотим полностью изменить правила взлета в классе TMilitaryPlane. Тогда реализация метода TakeOff этого класса будет иметь такой вид:

 

procedure TMilitaryPlane.TakeOff(Dir: Integer);

begin

{ Полностью новый алгоритм }

end;

 

Если нам необходимо унаследовать алгоритм метода предка и добавить новые действия, то структура метода будет такой:

 

procedure TMilitaryPlane.TakeOff(Dir: Integer);

begin

{ Сначала вызываем метод предка }

inherited TakeOff(Dir);

{ Далее следует новый код }

end;

 

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

Обратите внимание на то, что метод TakeOff объявлен в секции protected класса TAirplane. Так, метод объявленный в секции private, перекрыть нельзя. Скрытые элементы класса невидимы ни из программы, ни их дочерних классов. Размещение объявления некоторого элемента в секции protected делает его невидимым из программы, но доступным дочерним классам.

 

ПРИМЕЧАНИЕ. Имееся важное исключение из правила видимости скрытых (private) и защищенных (protected) элементов базового класса в его дочерних классах. Так, если родительский и производный класс объявлены в одном и том же модуле, то все скрытые элементы родительского класса доступны в дочернем классе. Если же дочерний класс объявлен в другом модуле, то скрытые поля и методы становятся недоступными. Защищенные элементы родительского класса доступны всем его дочерним классам незавсимо от того, в каком модуле объявлен тот или иной дочерний класс.

 

Если предполагается, что дочерний класс нуждается в собственном конструкторе, то в коде его реализации первым следует вызвать конструктор предка. Это необходимо для того, чтобы корректно проинициализировать поля родителя. Вызов конструктора предка также осуществляется с помощью ключевого слова inherited. Рассмотрим код конструктора класса TAirplane еще раз:

 

constructor TAirplane.Create(AName: string; AKind: Integer);

begin

inherited Create;

Name:= AName;

Kind:= AKind;

Status:= OnRamp;

case Kind of

Airliner: Ceiling:= 15000;

Commuter: Ceiling:= 10000;

PrivateCraft: Ceiling:= 5000;

end;

end;

 

Здесь первым делом мы вызываем конструктор базового класса. Но при объявлении класса TAirplane предок не указан. Дело в том, что общим предком всех классов в Object Pascal по умолчанию является класс TObject. Иллюстрация концепции наследования показана на рисунке 3.1.

TCivilPlane
Наследование позволяет создавать иерархии классов, которые отражают связи понятий и явлений реальной предметной области. Рассмтриваемый пример показывает, что класс TAirplane, который инкапсулирует общие принципы поведения летательного аппарата как элемента системы управления воздушным движением, может рассматриваться как базовый при уточнении понятий «гражданский» и «военный». На рисунке 3.1 это TMilitaryPlane и TCivilPlane. Далее, мы развиваем ветвь военных самолетов, вводя такие уточнения как «истребитель» (TFighter),

«бомбардировщик», (TBobmer),

«вертолет» (THelicopter) и т.д.

Дочерними классами истребителей являются конкретные их представители, ибо они имеют различные технические и маневренные характеристики, вооружение и т.п.

К рассмотренной здесь иерархии классов следует относиться лишь как к учебному примеру, иллюстрирующему концепцию наследования в объектно–ориентированном программировании. Для правильного построения иерархии классов разработчик должен знать как специфику предметной области, так и основы системотехники.

 




Поделиться с друзьями:


Дата добавления: 2015-04-29; Просмотров: 1973; Нарушение авторских прав?; Мы поможем в написании вашей работы!


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



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




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