Відмінності між версіями «Клас»

 
Рядок 47: Рядок 47:
  
 
===Посилання на класи===
 
===Посилання на класи===
 +
[[Зображення:Klas.gif|frame|справа|Змінна-об'єкт, екземпляр об'єкту в пам'яті, мінлива-клас і екземпляр класу в пам'яті]]
  
 
Мова Delphi дозволяє розглядати класи об'єктів як свого роду об'єкти, якими можна маніпулювати в програмі. Така можливість народжує нове поняття – '''клас класу'''; Його прийнято позначати терміном '''метакласи'''.
 
Мова Delphi дозволяє розглядати класи об'єктів як свого роду об'єкти, якими можна маніпулювати в програмі. Така можливість народжує нове поняття – '''клас класу'''; Його прийнято позначати терміном '''метакласи'''.
Рядок 69: Рядок 70:
 
Змінна типу TClass може посилатися на будь-який клас.
 
Змінна типу TClass може посилатися на будь-який клас.
 
Практична цінність посилань на класи полягає в можливості створювати програмні модулі, що працюють з будь-якими класами об'єктів, навіть тими, які ще не розроблені.
 
Практична цінність посилань на класи полягає в можливості створювати програмні модулі, що працюють з будь-якими класами об'єктів, навіть тими, які ще не розроблені.
 +
 +
==Класи загального призначення==
 +
Як показує практика, у більшості завдань доводиться використовувати однотипні структури даних: списки, масиви, множини і т.д. Від завдання до завдання змінюються лише їхні елементи, а методи роботи зберігаються. Наприклад, для будь-якого списку потрібні процедури вставки і видалення елементів. У зв'язку з цим виникає природне бажання вирішити задачу "в загальному вигляді", тобто створити універсальні засоби для управління основними структурами даних. Ця ідея не нова. Вона давно прийшла в голову розробникам інструментальних пакетів, які швидко наплодили безліч допоміжних бібліотек. Ці бібліотеки містили класи об'єктів для роботи зі списками, колекціями (динамічні масиви з перемінним кількістю елементів), словниками (колекції, індексовані рядками) та іншими "абстрактними" структурами. Для середовища Delphi теж розроблені аналогічні класи об'єктів. Їх велика частина зосереджена в модулі Classes. Найбільш потрібними для вас є списки рядків (TStrings, TStringList) і потоки (TSream, THandleSream, TFileStream, TMemoryStream і TBlobStream). Розглянемо коротко їх призначення та застосування.
 +
 +
===Класи для подання списку рядків===
 +
Для роботи зі списками рядків служать класи TStrings і TStringList. Вони використовуються в бібліотеці VCL повсюдно і мають набагато більшу універсальність, ніж та, що можна почерпнути з їх назви. Класи TStrings і TStringList служать для подання не просто списку рядків, а списку елементів, кожен з яких представляє собою пару рядок-об'єкт. Якщо з рядками не асоційовані об'єкти, виходить звичайний список рядків.
 +
 +
Клас TStrings використовується візуальними компонентами і є абстрактним. Він не має власних засобів зберігання рядків і визначає лише інтерфейс для роботи з елементами. Клас TStringList є спадкоємцем TStrings і служить для організації списків рядків, які використовуються окремо від керуючих елементів. Об'єкти TStringList зберігають рядки і об'єкти в динамічній пам'яті.
 +
 +
====Властивості класу TStrings====
 +
 +
*'''Count''': Integer – число елементів у списку.
 +
*'''Strings'''[Index: Integer]: string – забезпечує доступ до масиву рядків по індексу. Перший рядок має індекс, що дорівнює 0. Властивість Strings є основною властивістю об'єкта.
 +
*'''Objects'''[Index: Integer]: TObject – забезпечує доступ до масиву об'єктів. Властивості Strings і Objects дозволяють використовувати об'єкт TStrings як сховище рядків і асоційованих з ними об'єктів довільних класів.
 +
*'''Text''': String – дозволяє інтерпретувати список рядків, як одну велику рядок, в якій елементи розділені символами # 13 # 10 (повернення каретки та перекладів рядка).
 +
 +
Спадкоємці класу TStrings іноді використовуються для зберігання рядків виду Ім'я = Значення, зокрема, рядків INI-файлів. Для зручної роботи з такими рядками в класі TStrings додатково є такі властивості.
 +
 +
*'''Names'''[Index: Integer]: string – забезпечує доступ до тієї частини рядка, в якому міститься ім'я.
 +
*'''Values'''[Const Name: string]: string – забезпечує доступ до тієї частини рядка, в якому міститься значення. Вказуючи замість Name ту частину рядка, який знаходиться зліва від знаку рівності, ви отримуєте ту частину, що знаходиться праворуч.
 +
 +
====Управління елементами списку здійснюється за допомогою таких методів====
 +
 +
*'''Add'''(Const S: string): Integer – додає новий рядок S у список і повертає її позицію. Новий рядок додається в кінець списку.
 +
*'''AddObject'''(Const S: string; AObject: TObject): Integer – додає в список рядок S і асоційований з нею об'єкт AObject. Повертає індекс пари рядок-об'єкт.
 +
*'''AddStrings'''(Strings: TStrings) – додає групу рядків в існуючий список.
 +
*'''Append'''(Const S: string) – робить те ж, що і Add, але не повертає значення.
 +
*'''Clear''' – Видаляє із списку всі елементи.
 +
*'''Delete'''(Index: Integer) – видаляє рядок і асоційований з нею об'єкт. Метод Delete, також як метод Clear не руйнують об'єктів, тобто не викликають у них деструктор. Про це ви повинні подбати самі.
 +
*'''Equals'''(Strings: TStrings): Boolean – Повертає True, якщо список рядків у точності дорівнює тому, що передано в параметрі Strings.
 +
*'''Exchange'''(Index1, Index2: Integer) – змінює два елементи місцями.
 +
*'''GetText''': PChar – повертає всі рядки списку у вигляді однієї великої нуль-терминированной рядка.
 +
*'''IndexOf'''(Const S: string): Integer – повертає позицію рядка S у списку. Якщо заданий рядок у списку відсутня, функція повертає значення -1.
 +
*'''IndexOfName'''(Const Name: string): Integer – повертає позицію рядка, який має вигляд Ім'я = Значення і містить в собі Ім'я, рівне Name.
 +
*'''IndexOfObject'''(AObject: TObject): Integer – повертає позицію об'єкта AObject в масиві Objects. Якщо заданий об'єкт у списку відсутня, функція повертає значення -1.
 +
*'''Insert'''(Index: Integer; const S: string) – вставляє в список рядок S у позицію Index.
 +
*'''InsertObject'''(Index: Integer; const S: string; AObject: TObject) – вставляє в список рядок S і асоційований з нею об'єкт AObject в позицію Index.
 +
*'''LoadFromFile'''(Const FileName: string) – завантажує рядки списку з текстового файлу.
 +
*'''LoadFromStream'''(Stream: TStream) – завантажує рядки списку з потоку даних (див. нижче).
 +
*'''Move'''(CurIndex, NewIndex: Integer) – змінює позицію елемента (пари рядок-об'єкт) у списку.
 +
*'''SaveToFile'''(Const FileName: string) – зберігає рядки списку в текстовому файлі.
 +
*'''SaveToStream'''(Stream: TStream) – зберігає рядки списку в потоці даних.
 +
*'''SetText'''(Text: PChar) – завантажує рядки списку з однієї великої нуль-терминированной рядка.
 +
 +
===Класи для подання потоку даних===
 +
У середовищі Delphi існує ієрархія класів для зберігання і послідовного введення-виведення даних. Класи цій ієрархії називаються потоками. Потоки найкраще представляти як файли. Класи потоків забезпечують різне фізичне представлення даних: файл на диску, розділ оперативної пам'яті, поле в таблиці бази даних
 +
 +
====Опис класів подання потоку даних====
 +
'''TStream''' - Абстрактний потік, від якого успадковуються всі інші. Властивості і методи класу TStream утворюють базовий інтерфейс потокових об'єктів.
 +
 +
'''THandleStream''' - Потік, який зберігає свої дані у файлі. Для читання-запису файлу використовується дескриптор (handle), тому потік називається дескрипторних. Дескриптор – це номер відкритого файлу в операційній системі. Його повертають низькорівневі функції створення і відкриття файлу.
 +
 +
'''TFileStream''' - Потік, який зберігає свої дані у файлі. Відрізняється від ThandleStream тим, що сам відкриває (створює) файл по імені, переданому в конструктор.
 +
 +
'''TMemoryStream''' - Потік, який зберігає свої дані в оперативній пам'яті. Моделює роботу з файлом. Використовується для зберігання проміжних результатів, коли файловий потік не підходить із-за низької швидкості передачі даних.
 +
 +
'''TResourceStream''' - Потік, що забезпечує доступ до ресурсів в Windows-додатку.
 +
 +
'''TBlobStream''' - Забезпечує послідовний доступ до великих полях таблиць в базах даних.

Поточна версія на 17:54, 27 грудня 2011

Клас

Клас - Деяка абстракція сукупності об'єктів, які мають загальний набір властивостей і мають однакову поведінку, і визначається як список своїх членів. В об'єктно-орієнтованому програмуванні, класи використовуються для групування пов'язаних змінних та функцій. Клас описує набір інкапсульованих змінних екземпляра та методів (функцій), можливо, разом з реалізацією цих типів разом з конструктором, який може використовуватись для створення екземплярів класа.


Клас є зв'язанним пакетом, який складається із спеціальних метаданих часу компіляції. Він описує правила за якими діють об'єкти; ці об'єкти називаються "екземплярами" цього класа. Клас визначає структуру даних, що містить кожний екземпляр, і, також, методи (функції) які обробляють дані екземпляра та виконують завдання; ці методи часто називають "поведінкою". Метод є функцією, що має доступ до даних об'єкта. Клас є найспецифічнішим типом даних об'єкта по відношенню до окремого прошарку. Клас може мати представлення (метаоб'єкт) під час виконання програми, який надає допомогу в роботі з метаданими класа.


Клас визначає абстрактні характеристики деякої сутності, включаючи характеристики самої сутності (її атрибути або властивості) та дії, які вона здатна виконувати (її поведінки, методи або можливості). Наприклад, клас Собака може характеризуватись рисами, притаманними всім собакам, зокрема: порода, колір хутра, здатність гавкати. Класи вносять модульність та структурованість в об'єктно-орієнтовану програму. Як правило, клас має бути зрозумілим для не-програмістів, що знаються на предметній області, що, у свою чергу, значить, що клас повинен мати значення в контексті. Також, код реалізації класу має бути досить самодостатнім. Властивості та методи класу, разом називаються його членами.

Види класів

  • Базовий (батьківський) клас
  • Похідний клас (спадкоємець, нащадок)
  • Абстрактний (віртуальний) клас

Абстрактні (abstract) методи і класи тільки оголошуються, клас який містить абстрактні методи повинен оголоситися як абстрактний. На основі абстрактного класу можна тільки створювати інші класи, а вже від них об'єкти. Абстрактний клас може містити і звичайні (не абстрактні) елементи.

Члени класів

Клас визначається як список своїх членів. До членів класу відносяться його поля (властивості) і функції (методи). Кожному члену класу можна встановити його область доступу (access control level). Область доступу члена класу визначає ділянки коду, з яких до цього члену буде можливо звертатися. У більшості об'єктно-орієнтованих мов програмування підтримуються наступні області доступу:

private (закритий, внутрішній член класу) - звернення до члена допускаються тільки з коду методів класу, в якому цей член визначений. Будь-які спадкоємці класу вже не зможуть отримати доступ до цього члену;
protected (захищений, внутрішній член ієрархії класів) - звернення до члена допускаються з коду методів класу, в якому цей член визначений, або з будь-яких його класів-спадкоємців;
public (відкритий член класу) - звернення до члена допускаються з будь-якого коду.

Область видимості

Область видимості членів класу (тобто область коду, з якої до них можна звертатися за некваліфікованого імені - без вказівки імені класу чи об'єкта) не залежить від їх області доступу, і завжди збігається з кодом методів класу.

Область видимості самого класу по-різному визначається в різними мовами програмування. В одних мовах (таких як Delphi) усі класи мають глобальну видимість (з урахуванням видимості модуля), в інших (таких як Java) область видимості класу пов'язана з змістом його одиниці компіляції (в Java - з пакетом), в третіх (таких як C + + і C #) область видимості класу визначається просторами імен (), які задаються програмістом явно і можуть співпадати або не співпадати з одиницями компіляції.

Відносини між класами

  • Спадкування (Генералізація) - об'єкти дочірнього класу успадковують всі властивості батьківського класу.
  • Асоціація - об'єкти класів вступають у взаємодію між собою.
  • Агрегація - об'єкти одного класу, входять в об'єкти іншого.
  • Композиція - об'єкти одного класу, входять в об'єкти іншого і залежать один від одного за часом життя.
  • Клас-метакласи - ставлення, при якому примірниками одного класу є інші класи.

Класи в програмних модулях

Класи дуже зручно збирати в модулі. При цьому їх опис поміщається в секцію interface, А код методів – в секцію implementation. Створюючи модулі класів, потрібно дотримуватися наступних правил:

  • всі класи, призначені для використання за межами модуля, слід визначати в секції interface;
  • опис класів, призначених для вживання усередині модуля, слід розташовувати в секції implementation;
  • якщо модуль B використовує модуль A, то в модулі B можна визначати класи, породжені від класів модуля A.

Розробка класів

Класи розробляються для досягнення певної мети. Найчастіше програміст починає з нечітко обкресленої ідеї, яка поступово, у міру розробки проекту, поповнюється деталями. Іноді справа закінчується декількома класами, вельми схожими один на одного. Щоб уникнути подібного дублювання код в класах, слід розбити їх на дві частини, визначивши загальну частину в батьківському класі, а що відрізняються залишити в похідних. Оголошення класу повинне передувати його використанню. Як правило, прикладний програміст користується готовими базовими класами, причому йому зовсім не обов'язково розбиратися у всіх специфікаціях і у внутрішній реалізації. Проте, щоб використовувати базовий клас, треба обов'язково знати які члени даних і методи доступні.

Посилання на класи

Змінна-об'єкт, екземпляр об'єкту в пам'яті, мінлива-клас і екземпляр класу в пам'яті

Мова Delphi дозволяє розглядати класи об'єктів як свого роду об'єкти, якими можна маніпулювати в програмі. Така можливість народжує нове поняття – клас класу; Його прийнято позначати терміном метакласи.

Для підтримки метакласи введений спеціальний тип даних – посилання на клас (class reference). Він описується за допомогою словосполучення class of, Наприклад:

type
TTextReaderClass = class of TTextReader;

Змінна типу TTextReaderClass оголошується в програмі звичайним чином:

var
ClassRef: TTextReaderClass;

Значеннями змінної ClassRef можуть бути клас TTextReader і всі породжені від нього класи. Можливі наступні оператори:

ClassRef := TTextReader;
ClassRef := TDelimitedReader;
ClassRef := TFixedReader;

За аналогією з тим, як для всіх класів існує загальний предок TObject, у посилань на класи існує базовий тип TClass, визначений, як:

type
TClass = class of TObject;

Змінна типу TClass може посилатися на будь-який клас. Практична цінність посилань на класи полягає в можливості створювати програмні модулі, що працюють з будь-якими класами об'єктів, навіть тими, які ще не розроблені.

Класи загального призначення

Як показує практика, у більшості завдань доводиться використовувати однотипні структури даних: списки, масиви, множини і т.д. Від завдання до завдання змінюються лише їхні елементи, а методи роботи зберігаються. Наприклад, для будь-якого списку потрібні процедури вставки і видалення елементів. У зв'язку з цим виникає природне бажання вирішити задачу "в загальному вигляді", тобто створити універсальні засоби для управління основними структурами даних. Ця ідея не нова. Вона давно прийшла в голову розробникам інструментальних пакетів, які швидко наплодили безліч допоміжних бібліотек. Ці бібліотеки містили класи об'єктів для роботи зі списками, колекціями (динамічні масиви з перемінним кількістю елементів), словниками (колекції, індексовані рядками) та іншими "абстрактними" структурами. Для середовища Delphi теж розроблені аналогічні класи об'єктів. Їх велика частина зосереджена в модулі Classes. Найбільш потрібними для вас є списки рядків (TStrings, TStringList) і потоки (TSream, THandleSream, TFileStream, TMemoryStream і TBlobStream). Розглянемо коротко їх призначення та застосування.

Класи для подання списку рядків

Для роботи зі списками рядків служать класи TStrings і TStringList. Вони використовуються в бібліотеці VCL повсюдно і мають набагато більшу універсальність, ніж та, що можна почерпнути з їх назви. Класи TStrings і TStringList служать для подання не просто списку рядків, а списку елементів, кожен з яких представляє собою пару рядок-об'єкт. Якщо з рядками не асоційовані об'єкти, виходить звичайний список рядків.

Клас TStrings використовується візуальними компонентами і є абстрактним. Він не має власних засобів зберігання рядків і визначає лише інтерфейс для роботи з елементами. Клас TStringList є спадкоємцем TStrings і служить для організації списків рядків, які використовуються окремо від керуючих елементів. Об'єкти TStringList зберігають рядки і об'єкти в динамічній пам'яті.

Властивості класу TStrings

  • Count: Integer – число елементів у списку.
  • Strings[Index: Integer]: string – забезпечує доступ до масиву рядків по індексу. Перший рядок має індекс, що дорівнює 0. Властивість Strings є основною властивістю об'єкта.
  • Objects[Index: Integer]: TObject – забезпечує доступ до масиву об'єктів. Властивості Strings і Objects дозволяють використовувати об'єкт TStrings як сховище рядків і асоційованих з ними об'єктів довільних класів.
  • Text: String – дозволяє інтерпретувати список рядків, як одну велику рядок, в якій елементи розділені символами # 13 # 10 (повернення каретки та перекладів рядка).

Спадкоємці класу TStrings іноді використовуються для зберігання рядків виду Ім'я = Значення, зокрема, рядків INI-файлів. Для зручної роботи з такими рядками в класі TStrings додатково є такі властивості.

  • Names[Index: Integer]: string – забезпечує доступ до тієї частини рядка, в якому міститься ім'я.
  • Values[Const Name: string]: string – забезпечує доступ до тієї частини рядка, в якому міститься значення. Вказуючи замість Name ту частину рядка, який знаходиться зліва від знаку рівності, ви отримуєте ту частину, що знаходиться праворуч.

Управління елементами списку здійснюється за допомогою таких методів

  • Add(Const S: string): Integer – додає новий рядок S у список і повертає її позицію. Новий рядок додається в кінець списку.
  • AddObject(Const S: string; AObject: TObject): Integer – додає в список рядок S і асоційований з нею об'єкт AObject. Повертає індекс пари рядок-об'єкт.
  • AddStrings(Strings: TStrings) – додає групу рядків в існуючий список.
  • Append(Const S: string) – робить те ж, що і Add, але не повертає значення.
  • Clear – Видаляє із списку всі елементи.
  • Delete(Index: Integer) – видаляє рядок і асоційований з нею об'єкт. Метод Delete, також як метод Clear не руйнують об'єктів, тобто не викликають у них деструктор. Про це ви повинні подбати самі.
  • Equals(Strings: TStrings): Boolean – Повертає True, якщо список рядків у точності дорівнює тому, що передано в параметрі Strings.
  • Exchange(Index1, Index2: Integer) – змінює два елементи місцями.
  • GetText: PChar – повертає всі рядки списку у вигляді однієї великої нуль-терминированной рядка.
  • IndexOf(Const S: string): Integer – повертає позицію рядка S у списку. Якщо заданий рядок у списку відсутня, функція повертає значення -1.
  • IndexOfName(Const Name: string): Integer – повертає позицію рядка, який має вигляд Ім'я = Значення і містить в собі Ім'я, рівне Name.
  • IndexOfObject(AObject: TObject): Integer – повертає позицію об'єкта AObject в масиві Objects. Якщо заданий об'єкт у списку відсутня, функція повертає значення -1.
  • Insert(Index: Integer; const S: string) – вставляє в список рядок S у позицію Index.
  • InsertObject(Index: Integer; const S: string; AObject: TObject) – вставляє в список рядок S і асоційований з нею об'єкт AObject в позицію Index.
  • LoadFromFile(Const FileName: string) – завантажує рядки списку з текстового файлу.
  • LoadFromStream(Stream: TStream) – завантажує рядки списку з потоку даних (див. нижче).
  • Move(CurIndex, NewIndex: Integer) – змінює позицію елемента (пари рядок-об'єкт) у списку.
  • SaveToFile(Const FileName: string) – зберігає рядки списку в текстовому файлі.
  • SaveToStream(Stream: TStream) – зберігає рядки списку в потоці даних.
  • SetText(Text: PChar) – завантажує рядки списку з однієї великої нуль-терминированной рядка.

Класи для подання потоку даних

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

Опис класів подання потоку даних

TStream - Абстрактний потік, від якого успадковуються всі інші. Властивості і методи класу TStream утворюють базовий інтерфейс потокових об'єктів.

THandleStream - Потік, який зберігає свої дані у файлі. Для читання-запису файлу використовується дескриптор (handle), тому потік називається дескрипторних. Дескриптор – це номер відкритого файлу в операційній системі. Його повертають низькорівневі функції створення і відкриття файлу.

TFileStream - Потік, який зберігає свої дані у файлі. Відрізняється від ThandleStream тим, що сам відкриває (створює) файл по імені, переданому в конструктор.

TMemoryStream - Потік, який зберігає свої дані в оперативній пам'яті. Моделює роботу з файлом. Використовується для зберігання проміжних результатів, коли файловий потік не підходить із-за низької швидкості передачі даних.

TResourceStream - Потік, що забезпечує доступ до ресурсів в Windows-додатку.

TBlobStream - Забезпечує послідовний доступ до великих полях таблиць в базах даних.