ООП в Delphi

Обектно-ориентирано програмиране на езика Object

Езикът за програмиране Object Pascal и неговият достоен наследник, програмната среда Delphi, са изградени на базата на теорията за обектно-ориентираното програмиране, която получи широко развитие в началото на 70-те и 80-те години на 20 век. По това време идеята за описване на програми от гледна точка на логически единици и взаимодействието между тях не беше толкова безспорна, а някои противници дори предизвикаха известно недоумение. Предимства на ООП пред традиционните методи за програмиране:

1. Тази концепция е най-съвместима с вътрешната логика на функциониране на операционната система Windows. Програма, състояща се от отделни обекти, е перфектно адаптирана да реагира на събития, възникващи в операционната система.

2. По-голяма надеждност на кода и възможност за повторно използване на използвани обекти.

Дори самото име на понятието „обектно-ориентирано програмиране“ показва, че ключовата фигура в ООП е обектът. Обектите са най-голямото постижение в съвременните технологии за програмиране. Те позволиха да се изгради програма не от чудовищна сложност от процедури и функции, а от тухли-обекти, предварително надарени с необходимите свойства. Хубавото на обектите е, че тяхната вътрешна сложност е скрита от програмиста, който просто използва готови строителни материали.

Всички характеристики, присъщи на даден обект от гледна точка на ООП, се наричат ​​полета. Всъщност това са променливи от определен тип, принадлежащи към обекта, в които са записани стойности, които отразяват състоянието на обекта. Методите на даден обект се използват за манипулиране на обект. На първо място, методите действат върху полетаобект. Ако методите на обект връщат стойност, те се изпълняват като функции, в противен случай методът се представя като процедура.

Един обект не може да се появи от нищото, средата за програмиране трябва по някакъв начин да бъде информирана за неговите характеристики. Следователно програмистът първо описва обекта; такова описание се нарича клас. Класът е чертеж на бъдещ обект, който отчита не само неговите конструктивни елементи (полета), но и определя начини за управление на тези елементи - методи на класа.

тип TPeople = клас

Класът съдържа полета (Име, Семейство) и методи (GetName, GetFamily).

Заглавките на методите, винаги следващи списъка с полета, действат като предни описания. Програмният код на методите е написан отделно от дефиницията на класа и ще бъде даден по-късно.

var Хора: TPeople;

Хора := TPeople.Create; //Разпределяне на памет за обекта

Create е така нареченият конструктор на обекти; той винаги присъства в класа и се използва за създаване и инициализиране на екземпляри. Когато се създава обект, място в паметта се разпределя само за неговите полета. Методите, подобно на редовните процедури и функции, се поставят в кодовата област на програмата; те могат да работят с всякакви екземпляри от своя клас и не се дублират в паметта. Веднъж създаден, обектът може да се използва в програмата: вземете и задайте стойностите на неговите полета, извикайте неговите методи. Достъпът до полетата и методите на даден обект се осъществява с помощта на квалифицирани имена, например:

Освен това, както при записите, можете да използвате оператора with, например:

Ако даден обект стане неизползван, той трябва да бъде изтрит чрез извикване на специалния метод Destroy, например:

Хора.Унищожи; // Освобождаване на паметта, заета от обекта

Унищожи етака нареченият деструктор на обекти; той присъства в класа заедно с конструктора и служи за премахване на обект от динамичната памет. След като деструкторът бъде извикан, променливата People става необвързана и не трябва да се използва за достъп до полетата и методите на обект, който вече не съществува. За да се разграничат обвързаните обектни променливи от несвързаните обектни променливи в програма, последните трябва да бъдат инициализирани на нула. Пример:

ако хората <> нула след това People.Destroy;

Извикването на деструктор за несъществуващи обекти е незаконно и ще доведе до грешка, когато програмата се изпълни. За да спаси програмистите от ненужни грешки, в обектите беше въведен предоставеният метод Free, който трябва да се извиква вместо деструктора. Самият метод Free извиква деструктора Destroy, но само ако стойността на променливата на обекта не е нула. Следователно последният ред в горния пример може да бъде пренаписан както следва:

След като обектът бъде унищожен, променливата People запазва стойността си, като продължава да препраща към място в паметта, където обектът вече не съществува. Ако тази променлива все още ще се използва, тогава е желателно да й се присвои стойност nil, за да може програмата да провери дали обектът съществува или не. По този начин най-правилната последователност от действия при унищожаване на обект трябва да бъде следната:

Със стандартната процедура FreeAndNil това може да се направи по-просто и елегантно:

FreeAndNil(Хора); //Еквивалентно на: хора. Безплатно; Хора := нула;

Стойността на една обектна променлива може да бъде присвоена на друга. В този случай обектът не се копира в паметта, а втората променлива просто се свързва със същия обект като първия:

var People1, People2: TPeople;

Обектите могат да действат в програмата не само като променливи, но и катоелементи на масив, полета за запис, параметри на процедури и функции. Освен това те могат да служат като полета на други обекти. Във всички тези случаи програмистът действително работи с указатели към екземпляри на обекти в куп памет. Поради това обектите са естествено адаптирани за създаване на сложни динамични структури от данни като списъци и дървета. За това не са необходими указатели към обекти.

Хора: масив от THuman;

Конструктори и деструктори

Конструкторите и деструкторите са специален вид методи. Създаването на обект включва разпределяне на памет за екземпляра и инициализиране на неговите полета, докато унищожаването му включва изчистване на полета и освобождаване на памет. Действията за инициализация и изчистване на полето са специфични за всеки конкретен клас обекти. Поради тази причина езикът Delphi ви позволява да замените стандартния конструктор Create и стандартния деструктор Destroy, за да правите каквото искате. Можете дори да дефинирате множество конструктори и деструктори (именувани от програмиста), за да предоставите различни процедури за създаване и унищожаване на обекти.

тип TPeople = клас Име: низ; семейство: низ; процедура GetName;

процедура GetFamily; конструктор Create; destrucot Унищожавам; край;

// Все още не правете нищо

Ако обектът съдържа вградени обекти или други динамични данни, тогава конструкторът е правилното място за създаването им. Конструкторът се прилага към клас или обект. Конструкторът създава нов обект само ако името му е предшествано от името на класа. Ако зададете името на вече съществуващ обект, той се държи по различен начин: не създава нов обект, а само изпълнява кода, съдържащ се в тялото на конструктора. Ако се приложи към клас,

тогава се изпълнява следнотопоследователност:

1. Заделя се място в динамичната памет за нов обект.

2. Разпределената памет се запълва с нули. В резултат на това всички цифрови полета

и полетата от порядъчен тип стават нулеви, низовите полета стават празни, а полетата, съдържащи указатели и обекти, стават нулеви.

3. След това се изпълняват действията на конструктора, зададени от програмиста.

4. Препратка към създадения обект се връща като стойност на конструктора. Типът на върнатата стойност е същият като типа на класа, използван в извикването (в нашия пример това е типът TPeople).

Така, въпреки че на пръв поглед синтаксисът на конструктора е подобен на извикване на процедура (не е дефинирана връщана стойност), конструкторът всъщност е функция, която връща създаден и инициализиран обект. Ако конструкторът се приложи към обект,

тогава конструкторът се изпълнява като обикновен метод. С други думи, не се създава нов обект, но полетата на съществуващ обект се инициализират отново. В този случай конструкторът не връща никаква стойност. Не всички обекти се държат правилно по време на повторна инициализация, тъй като програмистите рядко включват такава възможност в своите класове. Следователно на практика рядко се използва повторна инициализация.

Деструкторът унищожава обекта, към който е приложен:

В резултат на това се извършват:

1. Специфициран от програмиста код за прекратяване.

2. Освобождава се динамичната памет, заета от обекта.

Тялото на деструктора обикновено трябва да унищожава вградени обекти и динамични данни, обикновено създадени от конструктора. Подобно на обикновените методи, деструкторът може да има параметри, но тази функция се използва рядко.

Writeln('Въведете имелице');

В рамките на методите достъпите до полета и други методи се извършват като редовни променливи и подпрограми, без да се посочва екземплярът на обекта. Това опростяване се постига чрез използване на псевдопроменливата Self (стандартен идентификатор) в рамките на метода. Този допълнителен скрит параметър е необходим в случаите, когато създавате множество обекти от един и същи клас, така че всеки път, когато прилагате метод към един от обектите, той трябва да работи със собствените си данни и да не засяга своите братски обекти. Физически, Self е допълнителен имплицитен параметър, предаден на метода, когато се извика. Този параметър указва екземпляра на обекта, към който се прилага този метод. Практиката показва, че псевдопроменливата Self рядко се използва изрично. Трябва да се използва само когато писането на метод би довело до неяснота в компилатора.