"Класи в Pascal"
Завантажити презентаціюПрезентація по слайдам:
Об’єкти реального світу можна описати за допомогою величин, що характеризують стан об’єкта та його поведінку (що робить об’єкт або що з ним можна робити), поведінка змінює стан об’єкта. Для адекватного моделювання реального світу в програмах, потрібно мати сутність, яка поєднує дані та алгоритм. boolean integer (const) real real procedure function Ручка Готовність Розмір Ціна Колір Колір чорнила Запас чорнила Увімкнути Вимкнути Записати Змінитичорнило
Unit Pen_unit; type Tpen = class private ready: boolean; price: real; colour: TColor; paintColour: TColor; paintSupply: real; public function isReady: boolean; procedure SwitchOn; procedure SwitchOff; дані методи оголошення Оголошення класу відбувається в модулі, але це можна робити і в головній програмі.
procedure Write (aWord: string); procedure Rechange (aPaint: TColor); constructor Create (a, b: TColor; p, s: real); end; Implementation begin function Tpen.isReady: boolean; begin result := ready; end; procedure Tpen.switchOn begin ready:=paintSupply > 0; end; … end.
Program prg_1; uses Pen_unit; var a: Tpen; begin a:=Tpen.Create(cOrange, cBlack; 2.5, 125.7); a.Write(‘Hello, World!’); a.switchOff; a.Free; звільнити динамічну пам’ять end. В об’єктній моделі ObjectPascal усі екземпляри класів динамічні. Змінна об’єктного типу – це неявний вказівник або посилання на динамічну пам’ять, де можна розташувати екземпляр класу.
Екземпляр створюють за допомогою конструктора і знищують за допомогою деструктора. Кожен екземпляр класу має окрему пам’ять і власний набір полів. Усі екземпляри класу поділяють єдиний набір методів, оголошених у класі. constructor Tpen.Create(a, b: Tcolor; p, s: real); begin colour:=a; paintColor:=b; if p>=1.0 then price:=p else price:=1.0; if s>=100.0 then paintSupply:=s else paintSupply:=100.0; ready:=false; end;
Інкапсуляція - обмеження доступу до даних Це дозвіл доступатися до спільних даних обмеженій кількості методів, доступ для всіх організовується за посередництва відповідальних за це методів. Unit shape_1; Interface Type Trect = class(TObject) private a, b: real; public constructor Create(x, y: real); destructor Destroy; function square: real; function Perym: real;
Procedure WriteOut; Implementation begin constructor Trect.Create(x, y: real); begin a:=x; b:=y; end; destructor Trect.Destroy; begin writeln(‘Said “Bye”’); end; procedure Trect.writeOut; begin writeln(a, b, ‘Rectangle’); end; function Trect.Sguare: real; begin result:=a*b; end; function TRect.Perym: real; begin result:=2*(a+b); end;
constructor TRect.Create; begin a:=3; b:=4; end; end. Конструктор задає значення полів об’єкта, вони можуть бути (початкові значення) в тексті конструктора або передані через параметри. Імена параметрів повинні відрізнятися від імен полів. Деструктор – це метод, відповідальний за коректне звільнення пам’яті від екземпляру класу.
Program p_1; uses Shape_1; var s:array [1…100] of TRect; i:integer; m:real; begin … m:=s[1].Square; for i:=2 to 100 do if s[i].Square>m then m:=s[i].Square … end. Якщо частина коду написана двічі, виносимо її в окремий метод.
TrectB: Trect + getB, setB unit shape_2 interface uses shape_1 type TRectB = class(TRect); Клас отримує (успадковує) від поперднього класу всі поля і наслідує їх функціональність. public function getB:real; procedure setB(y; real); procedure writeOut(t:textfile); end; implementation function TRectB.getB:real; begin result:=b; end;
procedure TRuctB.setB(y:real); begin b:=y; calls; end; procedure writeOut(t:textfile); begin writeln(t, ‘Advanced Rect’, a, ‘x’, b); end; private діє разом з поділом на unit. Доступ ззовні модуля заборонено всім без винятку, всередині модуля дозволено підкласам. Для того, щоб підкласи базового класу мали доступ до окремих полів даних, їх розташовують в області доступу protected.
Program p2; uses shape_1; shape_2; var p:Trect; q:TRectB; begin p.TRect.Create; q:=Trect. Create(7, 12); q.setB(0.5) if p.square
Метод WriteOut у класі TRect оголошено звичайним чином як статичний метод такий, як square, perym,…тому в коді деструктора виклик WriteOut прив’язується на етапі компіляції до методу TRect.WriteOut, це називають раннім зв’язуванням. Для того, щоб деструктор викликав метод WriteOut потрібного класу, його оголошують віртуальним. Виклики віртуальних методів виконують за допомогою пізнього зв'язування, що відбувається на етапі виконання програми. Клас Tobject є базовим. Усі інші класи є його нащадками. Free – метод, який звільняє динамічну пам'ять. Destroy – деструктор.
Підклас успадковує від базового класу усі без винятку поля класу і наслідує його поведінку, це означає, що екземпляри підкласу здатні опрацьовувати такі ж повідомлення, як і екземпляри базового. Підкласові доступні усі public і protected методи базового класу, тому екземпляри підкласу можуть без перешкод і без змін використовувати методи базового класу. Дуже часто підклас змінює поведінку базового (перевизначає окремі методи) і/або доповнює (додає нові методи). Взаємозвязки між базовим і похідними класами
Для перевизначення методів є дві можливості: для звичайних (статичних) методів дозволено використовувати довільну сигнатуру, тобто, метод з тим самим іменем у підкласі може мати інший набір параметрів; Віртуадбні методи перевизначають завжди з ттою самою сигнатурою. var c, a, b: Trect; begin a:=TRect.Create(3, 4); b:=TRect.Create(4, 3); if a.Square > b.Square then c:=a else c:-b c.WriteOut(output); … end. копіювання вказівника
Отримання копії об'єкта Щоб отримати копію об'єкта, необхідно створити додатковий конструктор, який прийматиме параметром об'єкт того ж класу: d:=TRect.CopyCreate(a)
Раннє і пізнє зв'язування Приклад: купівля кілограму апельсинів. Ми заздалегідь знаємо, що нам потрібно купити 1 кг апельсинів. Тому ми беремо невеликий пакет, небагато, але достатньо грошей, щоб вистачило на цей кілограм. Виходячи з будинку, ми не знаємо чого і скільки нам потрібно купити. Тому ми беремо машину(а раптом буде багато всього і важко нести?), запасаємося пакетами великих і малих розмірів і беремо якомога більше грошей. Їдемо на ринок і з'ясовується, що потрібно купити тільки 1 кг апельсинів.
При застосуванні раннього зв'язування, ми ніби говоримо компілятору: "Я точно знаю, чого я хочу. Тому жорстко(статично) зв'язуй усі виклики функцій". При застосуванні механізму пізнього зв'язування ми говоримо компілятору: "Я доки не знаю, чого я хочу. Коли прийде час, я повідомлю, що і як я хочу". Висновки: Таким чином, під час раннього зв'язування методи зв'язуються при першій слушній нагоді. У пізньому зв'язуванні реалізований спеціальний механізм, який визначає, як відбуватиметься зв'язування, що викликається і викликає методи, коли виклик буде зроблений фактично. Очевидно, що швидкість і ефективність при ранньому зв'язуванні вищі, ніж при використанні пізнього зв'язування. У той же час, пізнє зв'язування забезпечує деяку універсальність зв'язування.
Адресу динамічного методу міститиме таблиця того класу, де він визначений TSquare = class(TRect) constructor Create(x: real); procedure WriteOut(var t:textfile); end; //public можна упустити. constructor TSquare.Create(x: real ); begin inherited Create(x, x); end; override
Name() – overload Name(x) – override Tshape TRect TCircle TRectB TSquare a, s P-4a S=a2 TRect b P=2(a+b) S=ab TRectB
Tshape = clas(TObject) private s:real; protected procedure Calc S; virtual; abstract; public function Perym: real; virtual; abstract; function Square: real; procedure WriteOut(var T: textfile); virtual; absract; destructor Destroy; override; end; function TShape Square: real; begin result:=s; end;
Tshape 3d TPiramide TConus TCylindr TParalelepiped base: TShape Tshape 3d = class(TObject) private base: Tshape; h: real; end; Циліндр Конус Піраміда Паралелепіпед V=Sосн.h V = Sосн.h V= Sосн.h V=Sосн.h …
Кожен клас повинен містити свій конструктор. TShape 3d base: TShape; h: real; base.Square; v; a side.Square; v; a surf.Square; v; a Volume; v; a WriteOut; v; a
function TShape3d.base.square: real; begin result:=base.Square(); end; constructor TCylindr.Create(a, b: real); begin base:=TCircle.Create(a); h:=b; end; constructor TParalelepiped.Create(x, y, z: real); begin base:=TRect.Create(x, y); h:=z; end;
function TDirectShape.volume: real; begin result:=base.square*h; end; Завдання: Задано виміри 12 різних об'ємних фігур, потрібно надрукувати інформацію про кожного з них, знайти фігуру з найбільшим об'ємом і з найменшою повною поверхнею.
const n=12; type mas=array[1…n] of TShape3d var a: mas; k, i: integer; x, y, z: real; for i:=1 to n do A[i].writeOut; begin for i:=1 to n do begin read(k); case k of Cylindr: begin readln(x, y); A[i]:=Tcylindr.Create(x, y);
Paralelepiped: begin readln(x, y, z); A[i]:= Tparalelepiped.Create(x, y, z); end; … end; … end. TRectAB = class; private a,b: real; public function getB(): real; procedure setB(x: real); function Square(): real; procedure WriteOut();
constructor Create(x, y: real); end; … begin readln(size); R:=TRectAB.Create(size, 7); R.setA(R.getA + z); TRect_AB = class private Fa, Fb: real; // field protected function getA(): real; function getB(): real; procedure setA(x: real); procedure setB(x: real);
public constructor Create(x; y: real); function Square(): real; property a: real: read getA write setA; property b: real: read getB write setB; end; Property описує інтерфейсний елемент, його використовують для неявного виклику методів. begin R:=TRect_AB.Create(size, 7); R.a:=R.a+2;
Property – новий спосіб доступу. Ключові слова read і write вказують чи буде для властивості доступ для читання і для запису відповідно. Кожна з цих частин може бути відсутня
Схожі презентації
Категорії