ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

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

     

    Інформатика, програмування

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

    Об'єкт можна порівнювати з чорним ящиком. Фокусник кладе в нього хусточку, говорить заповітне заклинання, і витягує кролика. Так само і ми. Ми можемо ініціалізувати об'єкт, або він сам ініціалізується значеннями за замовчуванням, викликати потрібний метод об'єкта, і отримати результат. Нас мало цікавить те, що в ньому конкретно відбувається, якщо об'єкт вже досить добре налагоджений. Основна ідея об'єктно-орієнтованого підходу полягає в наявності інтерфейсу, що служить для поліморфного поводження з об'єктом і його нащадками. За рахунок наявності інтерфейсу легко досягається повторне використання коду. Багато програмістів, перехідні від процедурного програмування до об'єктно-орієнтованого програмування справедливо зауважують, що вони можуть зробити все те ж саме і без використання об'єктів. Об'єктно-орієнтоване програмування - це всього лише угода про правила побудови програм. Вся міць об'єктної орієнтації розкривається у великих проектах, або при написанні великої кількості однотипних програм, наприклад програм, що працюють з базами даних. За рахунок повторного використання коду досягається простота в роботі програміста (накопичення досвіду), скорочується розмір програми (методи об'єктів одного типу або методи, успадковані від предків нащадками існують в єдиному екземплярі), самодокументіруемость, а значить і більше простоти при налагодження (об'єкти описуються в певному місці програми окремо від реалізації), простота супроводу програми (не змінюючи інтерфейс об'єкта, Ви можете змінити реалізацію методів) і т.д. Але, це тільки в ідеалі. На самом справі достатньо просто перекрутити постулати об'єктної орієнтованості. Всі залежить від правильності і лаконічності дерева успадкування Вашої бібліотеки об'єктів. Нам пощастило, Ми можемо використовувати у своїй роботі останнє досягнення в області об'єктно-орієнтованого програмування - продукт компанії 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 для того, щоб програміст міг скористатися інспектором об'єктів для написання процедури обробки події.

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

    Банников. Н.А. Об'єктно-орієнтований підхід до програмування.

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

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status