Допомога у написанні освітніх робіт...
Допоможемо швидко та з гарантією якості!

Объектно-ориентированный підхід до програмування

РефератДопомога в написанніДізнатися вартістьмоєї роботи

Суть объектно-ориентированного підходи до програмування залежить від трьох принципах: инкапсуляции, успадкування і полиморфизме. Для надійної роботи програми, Ви повинні безпосередньо звертатися до полях об'єкта. Натомість, Ви повинні звертатися через спеціальні методи, які можуть опинитися перевірити, наприклад, на допустимість значення заданому інтервалі чи одночасно виконати додаткову роботу… Читати ще >

Объектно-ориентированный підхід до програмування (реферат, курсова, диплом, контрольна)

Объектно-ориентированный підхід до программированию

Объект можна порівнювати з чорним ящиком. Фокусник кладе до нього хустинка, каже заповітне заклинання, і витягає кролика. Також і ми. Ми можемо форматувати об'єкт, або вона сама инициализируется значеннями за умовчанням, викликати потрібний метод об'єкта, й одержати результат. Нас мало цікавить те, що він конкретно відбувається, якщо об'єкт досить добре налагоджений. Основна ідея объектно-ориентированного підходу залежить від наявність інтерфейсу, який служить для полиморфного роботи з об'єктом та її нащадками. за рахунок наявності інтерфейсу легко досягається повторне використання коду. Багато програмістів, перехідні від процедурного програмування до объектно-ориентированному програмування справедливо помічають, що можуть докласти зусиль той самий і без використання об'єктів. Объектно-ориентированное програмування — це лише угоду щодо правил побудови програм. Уся міць об'єктної орієнтації розкривається у великих проектах, або за написанні великого кількості однотипних програм, наприклад програм, які працюють із базами даних. за рахунок використання коду досягається простота у роботі програміста (накопичення досвіду), скорочується розмір програми (методи об'єктів одного типу чи методи, наслідувані від предків нащадками перебувають у єдиному примірнику), самодокументируемость, отже, і більше простоти при налагодженні (об'єкти описуються у певному місці програми окремо від реалізації), простота супроводу програми (не змінюючи інтерфейс об'єкта, Ви можете змінити реалізацію методів) тощо. Але, це тільки в ідеалі. Насправді справі не так важко перекрутити постулати об'єктної орієнтованості. Усі залежить від правильності і лаконічності дерева наслідування Вашої бібліотеки об'єктів. Нам пощастило, Ми можемо використати у роботі останнє досягнення у сфері объектно-ориентированного програмування — продукт компанії Borland-Inprise Delphi. При подальшому читанні тексту, якщо Вам буде відразу щось незрозуміло, то продовжуйте читати далі. У такій складній темі важко послідовно викласти усі клопоти з порядку, т.к. багато запитань переплітаються з складнішими і навпаки. Під час читання тексту, Ви складете повне уявлення теми.

Объектно-ориентированное программирование.

Объект в Delphi представляє з себе спеціальну структуру, що описує поля, властивості і методи об'єкта — class. Предком всім об'єктів служить class Tobject. Давайте розглянемо простий объект.

Type.

TmyObject = class (TObject).

Private // закрита часть.

AmyField: Integer; // Свойство.

Protected // Захищена часть.

Procedure SetMyField (Val: Integer); // Процедура записи властивості класса.

Public // Відкрита часть.

Constructor Create; // Конструктор

Destructor Destroy; override; // Деструктор

Property MyField: Integer read AmyField write SetMyField; // Властивість класса.

End;

Имена класів прийнято розпочинати з літери T, але ці просто угоду, а чи не правило. Можете назвати Ваш об'єкт як хочете. Проте, літера Т на початку імені класу — це правило доброго тону. Далі, вказується, що це клас нащадок від Tobject. Якщо ви запишіть TmyClass = class, однак ваш клас буде нащадком від Tobject. Далі, йде закрита частина інтерфейсу класу. Тут з’являються властивості і силові методи класу, які доступними тільки з методів цього ж самого класу, і буде недоступними й інших класових методів і з інших модулів програми. При успадкування класу, нащадок також матиме доступу до закритій його частині інтерфейсу. Іноді, таку поведінку класу незручно. Наприклад, при велику кількість інтерпретацій списку даних одного класу з іншого через відкриту частина інтерфейсу, при кожному зверненні, можливо, будуть перевірятися припустимі межі індексу списку. Це правильно, а може значно уповільнити роботу програми, тому було б непогано мати змога обмеженої кількості класів чи функцій дозволити доступом до закритій його частині, що вони могли звертатися до властивостями класу, оголошених у закритій його частині. Можливо, Ви писали на З++ і чудово знаєте, що в ній такі класи і функції називаються друзями. У Delphi цю можливість реалізується через оголошення дружніх класів та функцій щодо одного модулі програми, тобто. все друзям оголошені щодо одного модулі. Далі, йде захищена частина. Вона відрізняється від закритою тим, що з нащадка класу, Можете мати доступом до цієї маленької частини. Далі, йде відкрита частина інтерфейсу. Тут Можете оголосити властивості й фізичні методи класу, які доступні й інших класів, процедур і функцій. Є ще одне частина інтерфейсу — published (опублікована). Ця частина має місце біля нащадків від Tcomponent. Delphi використовує цю частину інтерфейсу в інспектора об'єктів. При доступі до класу під час виконання програми, ця частина нічим не відрізняється від public. Тут можна буде оголошувати властивості і події класу. Усі властивості і будуть доступні з інспектора об'єктів, і Ви зможете редагувати їх під час розробки. Щоб працювати з класом, Ви повинні оголосити зміну об'єктного типу цього, потім форматувати її викликом конструктора.

Type.

TmyClass = class (TObject) // Оголошення класса.

end;

Var.

AmyClass: TmyClass; // Оголошення перемінної класса.

begin.

AmyClass:=TmyClass.Create; // Виклик конструктора, зверніть увагу, що викликається конструктор// TmyClass. Create, а чи не AmyClass.Create.

Try.

finally.

AmyClass.Free; // Знищення класса.

End;

end;

Классы в Delphi можна створювати лише у динамічної пам’яті, тому всі перемінні об'єктного типу — це покажчики на примірник класу в динамічної пам’яті. Типове ім'я конструктора — Create, типове ім'я деструктора — Destroy. Дотримуйтеся цього правила, якщо ні особливої потреби у протилежному.

Инициализация і руйнування об'єктів

Для оголошення конструктора використовується зарезервоване слово constructor, після якого йде ім'я конструктори і параметри, якщо потрібно. Конструктор повертає покажчик на примірник класу. У конструктора Tobject ім'я Create, тому в всіх нащадків цього є конструктор Create, хоча, в деяких класів й інші конструктори коїться з іншими іменами, наприклад у оброблювачів винятків. У тілі конструктора Можете викликати конструктор предка для ініціалізації закритій його частині предка значеннями за умовчанням, например:

unit MyUnit;

interface.

Type.

TmyClass = class (TComponent).

public.

constructor Create (AOwner: TComponent); override; // перевантажуємо конструктор предка.

end;

implementation.

Constructor TmyClass. Create (AOwner: TComponent);

Begin.

Inherited Create (Aowner); // Виклик конструктора предка.

… // Подальша ініціалізація объекта.

End;

Если ім'я конструктора предка збігаються з ім'ям нащадка, можна скоротити запис при виклик конструктора предка в конструкторі потомка:

Constructor TmyClass. Create (AOwner: TComponent);

Begin.

Inherited (Aowner); // Виклик конструктора предка.

… // Подальша ініціалізація объекта.

End;

Для знищення об'єкта служить деструктор. Деструктор оголошується з допомогою зарезервованого слова destructor, після якої ім'я деструктора. Деструктор щось повертає і немає параметрів. Я раджу Вам замість прямого виклику деструктора використовувати метод Free. Цей метод на відзнаку всіх класів в Delphi, т.к. наслідується від Tobject. Цей метод спочатку перевіряє нерівність покажчика класом nil, та був лише викличе Destroy. Це безпечніший спосіб знищити объект. unit MyUnit;

interface.

Type.

TmyClass = class (TComponent).

public.

constructor Create (AOwner: TComponent); override; // перевантажуємо конструктор предка.

destructor Destroy; override // Перевантажуємо деструктор предка.

end;

implementation.

destructor TmyClass. Destroy;

Begin.

… // Знищення объекта.

Inherited Destroy; // Виклик деструктора предка, для знищення закритих полів предка.

End;

Инкапсуляция

Суть объектно-ориентированного підходи до програмування залежить від трьох принципах: инкапсуляции, успадкування і полиморфизме. Для надійної роботи програми, Ви повинні безпосередньо звертатися до полях об'єкта. Натомість, Ви повинні звертатися через спеціальні методи, які можуть опинитися перевірити, наприклад, на допустимість значення заданому інтервалі чи одночасно виконати додаткову роботу з зміни стану об'єкта, залежно від зміни значення поля — і є інкапсуляція. Така можливість зовсім реалізується у класах через оголошення властивостей об'єкта. Властивість дозволяє обмежити права зміну значення поля організовує доступом до полю через методи. Ось приклад описи класу зі свойством:

Type.

TmyClass = class (TObject).

Private.

AmyField: Integer; // Оголошення поля цілого типа.

Protected.

Procedure SetMyField (Val: Integer); virtual; // Оголошення процедури для записи значення свойства.

Public.

Property MyField: Integer read AmyField write SetMyField; // оголошення свойства.

End;

Здесь бачимо, що властивість MyField є цілим типом. Воно доступно для читання і запис, т.к. оголошено методи read і write. Процедура, організує запис значення оголошено в секції protected у тому, щоб у разі потреби, Ви могли перевантажити їх у нащадку. Насправді значення властивості зберігається на полі AmyField класу. Якщо ви не оголосите методу write, то властивість стане доступним лише з читання, аналогічно і з методом read. До речі, поля для зберігання значення властивості може і не, головне, щоб було оголошено методи доступу щодо нього. Наприклад, клас, який реалізує інтерфейс доступу до властивостями дисплея, міг би мати властивості завширшки висота в пикселях. Вам не обов’язково зберігати цих значень, т.к. можна викликати стандартну функцію Windows і навіть довідатися ширину і висоту екрана, тим паче, у процесі роботи ці значення можуть змінюватися при переключенні на другий режим. Методи запису і читання властивості підпорядковуються жорстких правил. Так для читання властивості, Вам необхідно оголосити функцію без формальних параметрів, возвращающую значення тієї самої типу, як і властивість. Для записи значення, Вам необхідно оголосити процедуру з однією параметром тієї самої типу, як і властивість. Якщо ролі методу для записи чи читання властивості Ви вказуєте ім'я поля для зберігання значення властивості, це аналогічно прямому доступу до цього полю. При компіляції такого способу звернення до властивості, код буде оптимізовано, тому це потягне ніяких додаткових витрат ресурсів комп’ютера. Зазвичай, такий метод звернення до полю застосовують для читання. Методи доступу до полях класу можуть виконувати додаткову роботу при переустановці значення поля класу. Так, при установці властивості Ttable. Active в true виробляється читання даних із таблиці бази даних на жорсткому диску, кілька разів змінюється стан об'єкта, посилаються події пов’язаним об'єктах, викликаються оброблювачі делегованих подій, які пише програміст, і потім переустанавливается значення властивості в true. Для присвоєння властивості значення за умовчанням, використовується ключовим словом default, например:

property Visible: boolean read Avisible write SetVisible default true;Это отже, що з запуску програми, компілятор встановити це властивість в true. Однак я геть настійно рекомендую Вам визначте властивостей за умовчанням в конструкторі класса. Вы можете мати індексовані властивості. Ось приклад реалізації такої класса.

Type.

TmyClass = class (TObject);

private.

AmyList: Tlist; // Контейнер указателей.

Protected.

Function GetMyList (Index: Integer): Pointer; // Функція доступу по чтению.

Procedure SetMyList (Index: Integer; Val: Pointer); // Процедура доступу по записи.

Public.

Property MyList[Index: Integer]: Pointer read GetMyList write SetMyList; // Оголошення индексированного свойства.

End;

Здесь бачимо, що властивість MyList индексированно — це важливий елемент списку покажчиків. У квадратних дужках Вам потрібно вказати список індексів та його типів. У випадку, індексом може навіть рядок символів. Далі йде тип властивості та фізичні методи запису і читання. Функція читання повинен мати список формальних параметрів з усіма індексами властивості і повертати значення тієї самої типу, як і властивість. Процедура записи повинен мати список формальних параметрів з усіма індексами властивості і параметр для передачі установлюваного значення тієї самої типу як і властивість. Велике значення має тут послідовність вказівки індексів і обов’язковість передачі значення властивості у процедурі записи останнім у списку формальних параметрів. Якщо индексированное властивість є основним і холодне поводження саме щодо нього виробляється частіше інших, можна оголосити його як default, тоді непотрібно вказувати ім'я властивість для доступу щодо нього, например:

Type.

TmyClass = class (TObject);

private.

AmyList: Tlist; // Контейнер указателей.

Protected.

Function GetMyList (Index: Integer): Pointer; // Функція доступу по чтению.

Procedure SetMyList (Index: Integer; Val: Pointer); // Процедура доступу по записи.

Public.

Property MyList[Index: Integer]: Pointer read GetMyList write SetMyList; default; // Оголошення индексированного властивості по умолчанию.

End;

Var.

MyClass: TmyClass;

Begin.

MyClass:= TmyClass. Create;

MyClass [3]: =AnyObject; // Аналогічно MyClass. MyList[3] ]: =AnyObject;

End;

Значение инкапсуляции в объектно-ориентированном програмуванні важко переоцінити. Чого вартий хоча б її, що у Delphi до 100% полів класів доступ організований через властивості.

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

Если Ви цього хочете змінити чи доповнити поведінка вже не існуючого класу, то немає жодної необхідності переписувати клас наново. Ви можете скористатися успадкуванням. Ви повинні оголосити, новий клас нащадок вже існуючого і додати у новий клас властивості й фізичні методи, які Вам необхідні чи перекрити існуючі методи лікування й свойства:

Type.

TmyFirstClass = class (TObject).

Private.

Protected.

Public.

Constructor Create (Val: Integer); virtual;

end;

TmySecondClass = class (TMyFirstClass).

Private.

AmyField: string; // Додали нове поле.

Protected.

Procedure SetMyField (Val: string); // Додали процедуру.

Public.

Constructor Create (Val: Integer); override; // Перевантажили конструктор

Property MyField: string read AmyField write SetMyField; // Додали свойство.

End;

Есть кілька правил області видимості об'єкта, які допоможуть Вам дати раду способами доступу до об'єктів і наслідування объектов:

Поля, властивості й фізичні методи секції public немає обмежень на видимість.

Поля, властивості й ефективні методи секції private, доступні лише у методах класу тут і у функціях, оголошених у тому самому модулі, що й клас.

Поля, властивості і силові методи секції protected теж доступні тільки з методів класу тут і функцій, оголошених у модулі, але де вони доступні в класах, є нащадками, у цьому однині і оголошених у інших модулях.

При описі нащадків, Можете змінювати область видимості методів і властивостей. Можна розширювати область видимості, але з звужувати. Тобто. є властивість в секції private, ви можете зробити його public, але з навпаки. Ось приклад розширення області видимости:

Type.

TmyClass=class (TObject).

Private.

AmyField: Integer;

protected.

property MyField: Integer read AmyField;

End;

TmySunClass = class (TMyClass).

Public.

Property MyField; // Тільки згадали їх у інший секції і він змінив область видимости.

End;

Унаследованные поля й фізичні методи нащадка є й у предка. При збігу імен предка і нащадка говорять про перекриття нащадком полів чи методів предка. По способу виклику методи класу можна розділити на статичні, віртуальні, динамічні, перегружаемые і абстрактні. Абстрактні методи немає реалізації і дружина мають бути обов’язково перекриті в нащадках. Абстрактними може лише віртуальні і динамічні методи, наприклад :

Type.

TmyClass=class (TObject).

protected.

procedure MyMethod (Val: Integer); virtual; abstract;

End;

Статические методи лікування й поля була в объектах-потомках перекриваються однаково: Можете без обмежень перекривати старі імена і навіть змінювати тип методів, т.к. при перекриття буде створено нову полі бою або метод з тим самим ім'ям. Перекритий метод предка доступний в нащадку через зарезервоване слово inherited.Type.

TmyClass=class (TObject).

protected.

procedure MyMethod;

End;

TmySunClass=class (TmyClass).

protected.

procedure MyMethod (Val: Integer);

End;

…procedure TmySunClass. MyMethod (Val: Integer);begin.

inherited MyMethod; // Метод предка без параметрів, а метод нащадка вже з параметром, тобто. ми поміняли тип процедуры.

end;

По вмовчанням все методи — статичні, тому їх адреси відомі на стадії компіляції, вони викликатися і під час програми най-швидшою способом. Віртуальні і динамічні методи описуються з допомогою спеціальних директив virtual чи dynamic. Ці методи може бути перекриті в нащадку однойменними методами, мають хоча б тип.

И нарешті, хочу сказати, що Delphi підтримувати не може множинного наслідування. Досягнення того самого, Вам доведеться використовувати просте успадкування одного з потрібних класів, а другий клас додати як полі, і організувати доступом до властивостями другого класу через властивості спадкоємця. Так з'єднати кілька класів. Інший спосіб — це створити класс-контейнер, у якому ролі полів будуть потрібні включені класи, а інтерфейс доступу до них організувати через властивості контейнера.

Полиморфизм

Указателю на примірник об'єктного типу то, можливо присвоєно адресу будь-якого примірника кожного з дочірніх типів. При зверненні до властивостями і методам через цей покажчик буде доступний саме примірник, адресу якого було присвоєно, а чи не предок. Це і поліморфізм. Тобто. Можете мати доступом до нащадку через покажчик об'єктного типу предка. Розглянемо пример:

Type.

TMyClass = class (TObject).

public.

procedure GetData: string; virtual; abstract;

end;

TmySun1Class = class (TMyClass).

Protected.

AmyField: string;

public.

procedure GetData: string; override;

end;

TmySun2Class = class (TMyClass).

Protected.

AmyField: Integer;

public.

procedure GetData: string; override;

end;

implementation.

procedure TmySun1Class. GetData: string;

begin.

Result:= AmyField;

end;

procedure TmySun2Class. GetData: string;

begin.

Result:=IntToStr (AmyField);

end;

Var.

MyClass: TmyClass;

Class1: TmySun1Class;

Class2: TmySun2Class;

Begin.

Class1:=TmySun1Class.Create;

Class2:=TmySun2Class.Create;

MyClass:= Class1;

Label1.Caption:= MyClass. GetData;

MyClass:= Class2;

Label2.Caption:= MyClass. GetData;

end;

Если подивитися цей код уважно, можна зрозуміти, що з компілятора немає можливості окреслити методу якого саме класу потрібно викликати. Тому, визначення адреси методу використовуються спеціальні таблиці, де зберігаються адреси на віртуальні і динамічні методи: VMT — таблиця віртуальних методів і DMT — таблиця динамічних методів. Коли компілятор зустрічає покажчик на віртуальний метод, він шукає його адресу в VMT, де зберігаються все адреси віртуальних методів класу успадкованих і перекритих, тому така таблиця займає багато місця пам’яті, хоч і спосіб виклику методу працює порівняно швидко. Динамічні методи викликаються повільніше, але займають менше пам’яті, т.к. у яких зберігаються адреси динамічних методів лише даного класу тут і їх індекси. При виклик динамічних методів проводиться пошук у цій таблиці, якщо метод не знайдено, то пошук триває в DMT предків до Tobject, де викликається стандартний оброблювач виклику динамічних методів. То навіщо ж нас увесь це потрібно? Під час проектування ієрархії класів предметної області, потрібно статичними робити методи, які змінюють своєї поведінки в нащадках, тобто. детальнішому розгляді явища. Динамічні і віртуальні методи можуть змінюватися під час переходу від загального до окремого. Згадайте клас Tfield, що є загальним предком всім классов-полей таблиці. Нащадки цього класу реалізують доступом до стовпчикам таблиці різних типів цілої числа до BLOB масиву, проте, Можете мати зручний доступом до цим нащадкам через покажчик типу Tfield і із нею однаково.

Перегрузка методів, процедур та зняття функцій

Перегрузка оголошується з допомогою зарезервованого слова overload. Розглянемо пример:

Type.

TmyDateClass=class (TObject).

private.

Adate: TdateTime;

Public.

Procedure SetDate (Val: TDateTime); overload; // Оголошуємо можливість перегрузки.

end;

TmySecondDateClass=class (TmyDateClass).

private.

Adate: TdateTime;

Public.

Procedure SetDate (Val: string); overload; // Оголошуємо можливість перегрузки.

End;…

implementationProcedure TmyDateClass. SetDate (Val: TDateTime);

Begin.

Adate:=Val;

End;

Procedure TmySecondDateClass. SetDate (Val: string);

Begin.

Adate:=StrToDate (Val);

End;

Во час програми, ви можете використовувати на другий клас обидва методу SetDate. Якщо ви передасте як параметра рядок, він викликаний метод другого класу, і якщо TdateTime, то метод предка. Можна перевантажувати і віртуальні методи, лише замість override потрібно використовувати reintroduce, например:

Type.

TmyDateClass=class (TObject).

private.

Adate: TdateTime;

Public.

Procedure SetDate (Val: TDateTime); overload; virtual; // Оголошуємо можливість перегрузки.

end;

TmySecondDateClass=class (TmyDateClass).

private.

Adate: TdateTime;

Public.

Procedure SetDate (Val: string); reintroduce; overload; // Оголошуємо можливість перегрузки.

End;Вы можете використовувати перевантаження й у процедур та зняття функцій необов’язково при успадкування, і навіть процедур та зняття функцій не класового типу, например:

Function Myfunction (Val: string): string; overload;

Begin.

Result:=Val+ «Ok! «.

End;

Function Myfunction (Val: Extended): extended; overload;

Begin.

Result:=Val/2;

End;

Или.

TmyDateClass=class (Tobject).

private.

Adate: TdateTime;

Public.

Procedure SetDate (Val: TDateTime); overload; // Оголошуємо можливість перегрузки.

Procedure SetDate (Val: string); overload; // Оголошуємо можливість перегрузки.

End;

Параметры по вмовчанням.

Если Вам потрібно створити функцію, що як параметрів майже завжди отримує один і той ж значення, та все ж іноді він може змінюватися, то Вам потрібно оголосити параметри за умовчанням як формальних параметрів, например:

Procedure MyProcedure (Val1: Extended; Val2: Integer = 2);

Begin.

End;

Тогда Ви зможете викликати її такими способами:

MyProcedure (42.33); // аналогічно MyProcedure (42.33, 2);

MyProcedure (15.6, 8);

Правило говорить, що це параметри за умовчанням мають бути наприкінці списку формальних параметрів процедури чи функції. Опускати параметри за умовчанням, можна тільки починаючи з кінця списку, тому потрібно упорядкувати параметри по вмовчанням за рівнем значимості.

Делегирование

Событие — це властивості процедурного типу, призначені до створення користувальницької реакцію зовнішні впливи. Події у Delphi реалізується з допомогою створення поля процедурного типу, і оголошення відповідного властивості класу, например:

Type.

TmyEvent = procedure (Sender: Tcomponent); of object; // визначення процедурного типа.

TmyClass=class (Tcomponent).

Private.

FmyEvent: TmyEvent;

Protected.

Procedure DoMyEvent;

published.

property OnMyEvent: TmyEvent read FmyEvent write FmyEvent;

end;

Допустим, Ви визначили функцію function MyProcedure (Sender: Tcomponent) в обробці події з допомогою інспектора об'єктів чи написали вручну, і нальоту присвоїли об'єкту: MyClass. OnMyEvent:=MyProcedure. При наступі певних умов Ваш клас може викликати процедуру DoMyEvent, де буде викликана Ваша процедура MyProcedure так:

Procedure TmyClass. DoMyEvent;

Begin.

If Assigned (FmyEvent) then FmyEvent (Self);

End;Мы бачимо, що було перевірений покажчик на користувальницьку процедуру обробки події, і коли він дійсний, то викликається користувальницька процедура — і є делегування. Зверніть увагу, що розмістив властивість OnMyEvent в секції published у тому, щоб програміст міг скористатися інспектором об'єктів для написання процедури обробки події.

Список литературы

Банников. Н.А. Объектно-ориентированный підхід до программированию.

Для підготовки даної роботи було використані матеріали із сайту internet .

Показати весь текст
Заповнити форму поточною роботою