Синицын Лекция16_17_Объекты и классы.ppt
- Количество слайдов: 38
Тема 14. Объекты и классы Ø Понятие объекта и класса Ø Свойства и методы класса Ø Свойство наследственности Ø Создание, уничтожение и операция присваивания объектов Ø Понятие полиморфизма Ø Статический, виртуальный и динамический способы реализации полиморфизма Ø Примеры использования объектов 2/9/2018 1
Понятие объекта и класса Ø С появлением языков Small. Talk и C++ в начале 80 -х годов возникла новая методология в технологии программирования – объектно-ориентированное программирование (ООП), основанное на более высоком уровне абстрагирования и модульности. Объекты придумали для упрощения разработки сложных программ и улучшения их качества. В языке Паскаль эта методология появилась, начиная с версии 5. 5 (1985 г. ). Ø Основным понятием ООП является объект, который в Delphi представляет собой переменную нового структурированного типа, описываемого с помощью ключевого слова Class. (Объекты всегда распределяются в куче, переменная типа класс это указатель) Ø Переменная типа Class под одним именем объединяет данные различных типов (поля) и процедуры их обработки (методы) Ø Объединение данных и процедур их обработки, называемое инкапсуляцией, с приданием ему свойств наследования и полиморфизма оказалось удивительно плодотворным 2/9/2018 2
Имя Структура объекта поля данных: a, b, x, y, u, v, … Свойства: определяются через Методы чтения и записи некоторых полей данных: sa(a), sb(b), … Методы (что умеет) Procedure Fp() Function Ff() Обработчики событий: (TForm 1. Button 1 Click) Методы, вызываемые как реакция на событие 2/9/2018 Объект Delphi Объектноориентированная программа – это совокупность объектов и способов их взаимодействия. Обмен между ними происходит посредством сообщений 3
• Unit u. Tob; Описание класса в разделе type • Interface • Type • Tobr=Class(Tobject) // родительский класс • a, b: Typr; • Property sa: Typr read a; //свойство • Function F 1(форм. п. F 1): T 1; // заголовки методов. . . • End; // Tobr • Tobp=Class(Tobr) // класс-потомок • c, d, e: Typp; • Procedure P 1(форм. п. Р 1); // методы Tobp • end; // Tobp • Implementation • Function Tobr. F 1; • Begin //описание методов • . . . • end; • Procedure Tobp. P 1; • begin • . . . • end; • end. // конец u. Tob Все поля должны иметь разные имена 2/9/2018 4
Реализация наследственности Ø Любой класс может быть порожден от другого класса. Ø Класс Tobp порожден от класса Tobr. Ø Ø Tobr – «класс родитель» , а Tobp – «класс-потомок» . Ø Ø Порожденный класс (Tobp) автоматически наследует поля и методы своего родителя (в приведенном примере a, b, F 1) и обогащает их новыми (c, d, e, P 1). Ø Принцип наследования позволяет эффективно использовать уже наработанный задел программ и на его основе создавать классы для решения все более сложных задач. Это приводит к тому, что программный продукт представляет собой ветвящееся дерево классов. Ø Ø Прародителем всех классов в Delphi является класс TObject. Все компоненты Delphi представляют собой созданные разработчиками классы. 2/9/2018 5
Создание, уничтожение объектов • Как всякая динамическая переменная, объект перед началом работы с ним должен быть создан конструктором класса TObject Create: • <Имя-переменной-типа-класс> : = <тип-класса>. Create; • После окончания работы с объектом, выделенную под него память необходимо освободить деструктором класса TObject Destroy или Free: • <Имя-переменной-типа-класс>. Free; • в состав любого пользовательского класса могут быть введены свои методы Сonstructor и Destructor с дополнительными к Create и Free функциями. • • Обычно это задание начальных условий совместно c Create или закрытие файлов перед уничтожением Free. 2/9/2018 6
• Unit 1; //вызывающая программа • Interface • Implementation • uses u. Tob; //подключение модуля • Var Obp 1, Obp 2: Tobp; • Obr 1: Tobr // объекты • Begin • . . . • Obp 1: =Tobp. Create; //создание объекта • Obp 1. sa: =10; //полю присвоить значения • Obp 1. P 1( ); //обращение к методу P 1 • Obp 1. Free; //уничтожение объекта • . . . • end. //Unit 1 2/9/2018 7
Понятие свойства класса • • Правила хорошего тона при ООП требуют: обращение к полям должно осуществляться посредством методов. Но каждый раз писать имя метода при обращении к полю не всегда удобно, поэтому придумали специальный механизм, регулирующий доступ к полям. • Свойство – это специальный механизм класса, регулирующий доступ к полям. Свойства объявляются с помощью ключевых слов • property… read…write…; • • var p: Tip; property sp: Tip read методr write методw. • • • Свойство связано с некоторым полем и указывает: методr – метод чтения содержимого поля (функция без параметров) (например, может сопровождаться выводом на печать) методw - метод записи в это поле (процедура с одним параметром имеющим тип свойства). 2/9/2018 8
• Пример описания свойства • Type • My. Сlass=class( ) • p: byte; • //получить значение p (методr ) • Function Getp: byte; • Begin • Getpole: =p; //отразить p на форме • label 1. caption: =inttostr(p); • end; • // присвоить полю значение p 0 (методw ) • Procedure Setp (p 0: byte); • Begin // проверить • if p 0>=0 then p: =p 0 else p: =0 • end; //cp – имя свойства • Property sp: byte read getp write Setp; (Property sp: byte read p; ) (Property sp: byte write Setp; ) • . . . 2/9/2018 end; // My. Сlass=class • 9
Работа со свойством Var • Myobj: Myclass; xt: integer; • begin • . . • Myobj: = Myclass. Create; • . . . • Myobj. sp: =10; • Myobj. Setp (10); //это эквивалентно • Myobj. p: =10; // так можно но не рекомендуется • • . . xt: =Myobj. sp; xt: =Myobj. Getp; //это эквивалентно xt: =Myobj. p; //так можно но не рекомендуется • . . . • end; 2/9/2018 10
Свойства • Фактически, свойства «живут» только до компиляции программы, во время которой заменяются методами или полями. • В реальности происходит присваивание значения полю p (а не свойству cp). • В отличие от полей свойства не занимают места в памяти и служат для указания транслятору что ему делать. 2/9/2018 11
операция присваивания объектов Ø Операция присваивания, например, obp 2: =obp 1; приводит к копированию только указателя! Ø Переменной родительского типа можно присвоить значение переменной типа потомка, например, obr 1: =obp 1. Ø Обратное же присваивание запрещено. Ø Однако, если переменная родительского типа указывает на объект, фактически соответствующий переменной типа потомка, то при необходимости ее можно преобразовать к типу потомка с помощью оператора приведения объектных типов as : obp 2: = obr 1 as Tobp; 2/9/2018 12
Понятие полиморфизма Ø Свойство полиморфизма позволяет использовать одинаковое название метода для решения сходных но несколько отличающихся у разных родственных классов задач. Ø Ø Например, метод Add (добавить) имеется у многих компонент Delphi, хотя в каждой компоненте реализуется по разному. Ø Обеспечивается это тем, что в классе-потомке метод переписываются по новому алгоритму, т. е. перекрывается. В результате в объекте-родителе и объекте-потомке будут действовать два одноименных метода с разными алгоритмами. Ø Obp 1. Add; Obr 1. Add; действуют по разному Ø Это и называется полиморфизмом объектов. 2/9/2018 13
Пример простого перекрытия методов Ø Предположим, что требуется создать пакет стандартных программ для решения однотипных уравнений (в общем случае задач), которые можно расположить в порядке увеличения сложности и преемственности. Ø Например, решить уравнения- линейное, квадратное, … Ø 1)ах+b=0; a[0]*x+ a[1]=0 Ø 2)ах2+bx+c=0; a[0]*x 2+ a[1]*x+a[2]=0 Ø 3)и т. д. Ø Начнем проектирование пакета программ с составления класса-прародителя 2/9/2018 14
1)ах+b=0 Описание родительского класса в разделе type • Unit u. Tob; • Interface • Type • Tur 1=Class(Tobject) • a, xi: array of extended; //массивы • n: word; • Lw: Text. File; • procedure Init(no: word; • const ao: array of extended); • procedure Solution; • procedure Resultw(File. N: string); • end; // Tur 1 • Implementation • . . . 2/9/2018 15
• Implementation • Var i: word; • procedure Tur 1. Init; • begin n: =no; • Set. Length(x, n); set. Length(a, n+1) • for i: =0 to n do a[i]: =ao[i]; • end; • procedure Tur 1. Solution; • begin • x[0]: =-a[1]/a[0] • end; • procedure Tur 1. Resultw; • begin • Assign(Lw, File. N); Rewrite(Lw); • for i: =0 to n do Writeln(Lw, a[i]); • for i: =0 to n-1 do Writeln(Lw, x[i]); • Close(Lw); 2/9/2018 • end; 16
Решение 1) 2 х+4. 6=0 • Var Our 1: Tur 1; • . . . • Begin • Our 1: =Tur 1. Create; • Our 1. Init(1, [2, 4. 6]); • Our 1. Solution; • Our 1. Resultw(’My. Sol’); • Our 1. Free; • end; • Результат: a 0=2 a 1=4. 6 • x 0=-2. 3 2/9/2018 17
• Класс потомок для ах2+bx+c=0; • Здесь достаточно переписать 1 метод Solution • Метод ввода данных и вывода результата будем брать родительский • . . . • end; // Tur 1 • Type • Tur 2=Class(Tur 1) • procedure Solution; • end; 2/9/2018 //Tur 2 18
• Реализация метода родителя • Implementation • . . //методы Tur 1 • • procedure Tur 2. Solution; • Var d: extended; • begin • d: =sgrt(sqr(a[1])-4*a[0]*a[2]); • x[0]: =(-a[1]+d)/(2*a[0]); • x[1]: =(-a[1]-d)/(2*a[0]); • end; • 2/9/2018 19
Решение 1. 2 х2+5 x+6. 2=0 • • Var Our 2: Tur 2; . . . . Our 2: =Tur 2. Create; Our 2. Init(2, [1. 2, 5, 6. 2]); Our 2. Solution; Our 2. Resultw(’My. Sol’); Our 2. Free; • В качестве упражнения напишите класс-потомок для кубического уравнения • Поля данных не перекрываются. Их можно только дополнять в потомках, но не переопределять 2/9/2018 20
Взаимодействие объекта с методами q • • Ø Ø При объявлении в разделе var и создании create Var ur 1, up 1: Tur 1; ur 2: Tur 2; ur 1: =Tur 1. Create; up 1: =Tur 1. Create; ur 2: =Tur 2. Create; каждый объект располагается по некоторому адресу. Причем создается столько копий полей данных сколько создано объектов , Ø методы же хранятся в одном экземпляре. • Может возникнуть вопрос, как при обращении к методу ur 1. Solution; ur 2. Solution; • удается определить, с какими полями работать, что делать? • Каждый раз, когда вызывается метод, ему через неявный параметр-указатель с именем Self, передается адрес того экземпляра объекта, который обращается к методу. 2/9/2018 21
Статический, виртуальный и динамический способы реализации полиморфизма Ø Полиморфизм можно организовать по-разному: • используя раннее связывание метода с полями объекта, • используя позднее связывание. Ø Статические методы: характеризуются тем, что связывание метода с полями объекта осуществляется во время компиляции (раннее связывание). Предыдущие листинги иллюстрируют статические методы. Ø Виртуальные и динамические методы: связываются с объектом во время выполнения программы (позднее связывание). Ø Если метод объявлен виртуальным или динамическим, то нельзя менять типы и число параметров. Ø Позднее связывание методов позволяет реализовать казалось бы удивительную способность родительского метода использовать методы своих потомков. 2/9/2018 22
Реализации позднего связывания • Замещаемый одноименный метод родителя объявляется как динамический или виртуальный с помощью ключевых слов Procedure Ris; dynamic; или Procedure Ris; virtual; • В потомке замещающий метод объявляется директивой Procedure Ris; override; • Вызов перекрытого метода родительского класса в одноименном методе потомка достигается с помощью зарезервированного слова Inherited Ris; (унаследованный). 2/9/2018 23
Пример организации перекрытия при позднем связывании • Interface • Type • Tobr=Class(Tobject) • . . . • Procedure Ris; virtual • end; // Tobr • Tobp=Class(Tobr) • . . . • Procedure Ris; override; • end; // Tobp • Implementation • Function Tobr. ris; begin (рисует что-то) end; • • Function Tobp. ris; • begin • Inherited Ris; //рисуем то что может родитель • . . . дорисовываем чего не хватает 2/9/2018 • end; 24
Реализация позднего связывания • Встретив объявления dynamic или virtual, компилятор создает таблицы соответствия DMT и VMT. • • В этих таблицах помещаются адреса точек входа методов. • Таблица VMT “своего” класса хранится в каждом экземпляре объекта в особом, скрытом от программиста поле. • • Таблица DMT хранится в VMT. • • При каждом обращении к методу компилятор вставляет в соответствующую таблицу код, позволяющий извлечь затем из нее адрес точки входа в подпрограмму 2/9/2018 25
Таблицы VMT DMT q Отличие таблиц DMT и VMT в том, что o DMT класса содержит адреса только тех методов, которые объявлены как dynamic в данном классе o VMT класса содержит адреса всех виртуальных методов доступных из класса: как нововведенных, так и унаследованных от родителей. Ø Любой класс имеет VMT, т. к. в Delphi все классы являются потомками класса Tobject, который в свою очередь содержит виртуальные методы. Ø Более того VMT родителя повторяется в VMT наследника с добавлением в нее сведений о виртуальных методах наследника, если таковые имеются Ø Использование таблиц VMT обеспечивает более быстрый поиск требуемого метода, но они и занимают много памяти при больших проектах. При использовании динамических методов таблицы DMT создаются только для тех классов, которые их имеют, т. е. они экономят память, но замедляют поиск. 2/9/2018 26
Пример абстрактного класса для рисования • Var Colr. Back: Tcolor; • Type • Tviz=class(Tobject) • Canvas: Tcanvas; • Colr. Line: Tcolor; • x, y, r: word; • Procedure Ris; virtual; abstract; • Procedure Draw(bl: boolean); • procedure Show; • procedure Hide; • procedure Mov. To(dx, dy, dr: integer); • end; • Метод Ris в родительском классе ничего не делает, его тело в разделе implementation отсутствует! • Объекты абстрактного класса не создаются! • Т. о. абстрактный класс является заготовкой для последующих классов потомков от него 2/9/2018 27
Описание методов абстрактного класса Прорисовка рисунка заданным цветом или цветом фона • Procedure Tviz. Draw(bl: Boolean); • begin • with Canvas do begin • if bl then begin pen. color: =colr. Line; • brush. color: =colr. Line end • else begin pen. color: =colr. Back; • brush. color: =colr. Back end; • ris; //процедура ris что-то рисует • //привязываясь к координанам x, y, r • end; 2/9/2018 28
Описание методов абстрактного класса • Procedure Tviz. Show; • begin • Draw(true); • end; (показать рисунок) • Procedure Tviz. Hide; • begin • Draw(false) • end; (стереть рисунок) • procedure Tviz. Mov. To; (передвинуть рис) • begin • Hide; • x: =x+dx; y: =y+dy; r: =r+dr; • Show; • end; 2/9/2018 29
Класс потомок 1 рисование круга • • Unit unit 2; interface uses Graphics; var Colr. Back: Tcolor; Type Tviz=class(Tobject) <Вставить описание которое приведено выше> end; • TKrug=class(Tviz) • x 1, y 1, x 2, y 2: word; • Constructor Create(x 0, y 0, r 0: word; • colr. Line 0: Tcolor; canvas 0: Tcanvas); • Procedure Ris; override; • end; • . . . 2/9/2018 30
Класс потомок рисования круга • • • implementation <Описание методов Tviz>. . . Constructor TKrug. Create; begin colr. Line: =colr. Line 0; canvas: =canvas 0; x: =x 0; y: =y 0; r: =r 0; end; • Procedure Tkrug. ris; • Begin • x 1: =x-r; x 2: =x+r; y 1: =y-r; y 2: =y+r; • Canvas. Ellipse(x 1, y 1, x 2, y 2); • end; • End. 2/9/2018 31
Программа рисования • unit Unit 1; • interface • uses • Windows, Messages, Sys. Utils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Ext. Ctrls, Com. Ctrls, Std. Ctrls; • type • TForm 1 = class(TForm) • Button 1: TButton; • Image 1: TImage; • . . • procedure Button 1 Click(Sender: TObject); • . . • end; • var • Form 1: TForm 1; • implementation • uses unit 2, Clipbrd; 2/9/2018 32
• • • • • var krug: Tkrug; Программа рисования okno 1: Timage; pxm 1, pym 1: word; xo, yo, ro: word; procedure TForm 1. Button 1 Click(Sender: TObject); begin okno 1: =Form 1. Image 1; colr. Back: =cl. White; pxm 1: =okno 1. Client. Width; pym 1: =okno 1. Client. Height; with okno 1. canvas do begin pen. color: =colr. Back; brush. color: =colr. Back; Rectangle(0, 0, Pxm 1, Pym 1); end; xo: =pxm 1 div 2; yo: =pym 1 div 2; ro: =10; Krug: =Tkrug. Create(xo, yo, ro, cl. Black, okno 1. canvas); krug. Show; End; 2/9/2018 33
Перемещения круга • • • • procedure TForm 1. Button 2 Click(Sender: TObject); begin //Увеличить круг Krug. Mov. To(0, 0, 3); end; procedure TForm 1. Button 3 Click(Sender: TObject); begin //уменьшить Krug. Mov. To(0, 0, -3); end; procedure TForm 1. Button 4 Click(Sender: TObject); begin //двигать вправо-вверх Krug. Mov. To(3, 3, 0); end; procedure TForm 1. Button 5 Click(Sender: TObject); begin //двигать влево-вниз Krug. Mov. To(-3, 0); end; 2/9/2018 34
Печать картинки и уничтожение объекта • procedure TForm 3. Button 8 Click(Sender: TObject); • begin //только для TImage !!! сохранить картинку • Clipboard. Assign(Image 1. Picture); • end; • procedure TForm 1. Bit. Btn 6 Click(Sender: TObject); • begin • krug. Free; • end; 2/9/2018 35
Круг+прямоугольник (тело) • • • • • Interfase TKr. Pr=class(Tkrug) dy 1: word; Constructor Create(x 0, y 0, r 0, dy 0: word; colr. Line 0: Tcolor; canvas 0: Tcanvas); Procedure ris; override; end; Implementation Constructor TKr. Pr. create; begin dy 1: =dy 0; Inherited Create(x 0, y 0, r 0, colr. Line 0, canvas 0); end; Procedure Tkr. Pr. ris; begin Inherited ris; Canvas. Rectangle(x 1, y 2, x 2, y 2+dy 1); end; 2/9/2018 36
Движение тела Создадим: Krpr: = Tkrpr. Create(xo, yo, ro, 4*ro, cl. Black, okno 1. canvas); Krpr. show; Двигаем: • procedure TForm 3. Button 6 Click(); • begin • //ход конем • krpr. Mov. To(10, 0, 0); • okno 1. Update; • sleep(200); • krpr. Mov. To(0, 5, 0); • end; 2/9/2018 37
Демонстрация конец 2/9/2018 38
Синицын Лекция16_17_Объекты и классы.ppt