реферат Простые операторы. Характеристика форм.docx. Лр операторы и выражения Delphi
Скачать 1.3 Mb.
|
Иерархия наследованияВновь возвратимся к очень важному ингредиенту ООП — наследованию. Мы уже знаем, что в основе концепции наследования лежит возможность строительства нового класса на базе уже существующего родительского класса. Благодаря наследованию дочерний класс впитывает в себя все родовые черты своего предка. Ограничений на длину цепочки наследования нет, в визуальной библиотеке компонентов Delphi объявлены классы, имеющие в родословной больше десятка предков. Таким образом, самый последний в древе наследования класс вбирает в себя все лучшее от всех своих предшественников. Для того чтобы понять какие уникальные возможности предоставляет программисту наследование, перейдем к практической стороне вопроса. В нашем распоряжении уже имеется класс TAutomobile, олицетворяющий все наши знания в области ООП. Попробуем развить первоначальный успех и создать программный класс, способный смоделировать пассажирский автобус — класс TAutobus. Автобус — это всего лишь разновидность автомобиля. У него, как и у автомобиля, есть двигатель, автобус также может набирать и снижать скорость движения. Одним словом, за основу нашего нового класса можно взять уже существующий TAutomobile и дополнить его всего одной возможностью — перевозить пассажиров (листинг 3.15). Листинг 3.15. Создание дочернего класса TAutobus type TAutobus=class(TAutomobile) private fPassenger:byte; //поле — число пассажиров procedure SetPassenger(Value:byte); //управление числом пассажиров public property Passenger:byte Read fPassenger Write SetPassenger; end; procedure TAutobus.SetPassenger(Value: byte); begin if (Value>=0) and (Value<=30) {ограничение числа пассажиров} then fPassenger:=Value else Raise Exception.Create('Число пассажиров должно быть от 0 до 30!'); end; ПолиморфизмКонцепция наследования порождает еще одну полезную черту классов — полиморфизм. Идея полиморфизма тесно связана с наследованием и заключается в праве экземпляра некоторого класса представлять все классы из его иерархической цепочки. Более того, благодаря полиморфизму мы получаем право скрывать (инструкция override) или переопределять (инструкция inherited) поведение унаследованных методов. Поэтому различные по содержанию процедуры и функции всевозможных объектов могут использовать одно и то же имя. Вызов же метода будет приводить к выполнению кода соответствующего конкретному экземпляру объекта. Листинг 3.16 поможет нам разобраться с основными принципами полиморфизма, он представляет собой модуль с цепочкой классов-самолетов. Листинг 3.16. Цепочка классов TAirframe, TAircraft и TJetAircraft unit Polymorph; interface uses SysUtils, Dialogs; type TAirframe = class //абстрактный класс планер procedure Fly; virtual; abstract; end; TAircraft = class(TAirframe) //самолет procedure Fly; override; //перезапись метода end; TJetAircraft = class(TAircraft) //реактивный самолет procedure Fly; override; //перезапись метода end; implementation procedure TAircraft.Fly; begin ShowMessage('Aircraft Fly'); end; procedure TJetAircraft.Fly; begin {позднее этот участок кода будет доработан} ShowMessage('JetAircraft Fly'); end; end. Первый из классов абстрактный. Это означает, что из него нельзя создать самостоятельный объект, но в этом и нет необходимости, задача планера TAirframe заключается в определении родовой черты всех своих потомков. Это, ни много ни мало, отвечающий за полет метод Fly(), который должен быть обязательно объявлен и заполнен программной логикой у всех наследников TAirframe — летательных аппаратов, классов TAircraft и TJetAircraft. Для того чтобы классы TAircraft и TJetAircraft получили право пользоваться одноименным методом Fly(), после объявления его заголовка использована специальная директива override, аннулирующая метод класса-предка. В результате в момент обращения к процедуре Fly() класса TAircraft выводится окно с текстовым сообщением "Aircraft Fly", процедуре Fly() класса TJetAircraft — "JetAircraft Fly". Одним словом, каждый из самолетов "летает" по-своему. Для того чтобы в этом убедиться, можно воспользоваться листингом 3.17. Листинг 3.17. Вызов метода Fly() экземпляра класса TJetAircraft with TJetAircraft.Create do begin Fly; Destroy; end; В ответ на вызов фрагмента кода (листинг 3.17) мы получим сообщение "JetAircraft Fly". А теперь настал час провести эксперимент с полиморфизмом, но для этого придется внести незначительное исправление в реализацию метода Fly() класса реактивного самолета TJetAircraft. Поэтому мы добавим в программный модуль всего одну строку с инструкцией inherited (листинг 3.18). Листинг 3.18. Усовершенствование метода Fly() класса TJetAircraft unit Polymorph; ... procedure TJetAircraft.Fly; begin inherited; ShowMessage('JetAircraft Fly'); end; end. Инструкция inherited уведомляет Delphi о том, что при вызове метода Fly() класс TJetAircraft намерен воспользоваться услугами одноименного метода Fly() своего класса-предка TAircraft. Если вы, после внесения исправлений, вновь вызовите предложенный в листинге 3.17 код, то на экране отобразится не одно, а целых два окна сообщений: сообщение "Aircraft Fly" (вызванное методом Fly() класса-предка TAircraft); сообщение "JetAircraft Fly" принадлежащее экземпляру класса TJetAircraft. |