Классы в Delphi. Члены классов. Области видимости членов класса. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Классы в Delphi. Члены классов. Области видимости членов класса.



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

В Паскале имеется четкое разграничение между понятиями объекта и класса.

Класс — это тип данных (как Integer или ТМу Record), а объект — конкретный сущест-

вующий в памяти компьютера экземпляр класса, переменная соответствующего

типа. В ранних версиях Паскаля существовала некоторая терминологическая пута-

ница, потому что первая реализация объектного подхода использовала для описания

84 Урок 1. Язык Delphi (Ob|ecl Pascal) и его использование

объектного типа данных ключевое слово object, и в то же время объектом называ-

лись экземпляры этого типа. Применять слово object можно и сейчас, однако подоб-

ная возможность поддерживается только для совместимости со старыми версиями

системы Delphi. Вместо ключевого слова object правильно использовать ключевое

слово class.

Классы имеют поля (как тип данных record), свойства (напоминающие поля, но имею-

щие дополнительные описатели, определяющие механизмы записи и считывания

данных, что позволяет повысить строгость декларирования внутренней структуры

класса) и методы (подпрограммы, которые обрабатывают поля и свойства класса).

ЗАМЕЧАНИЕ Поля, свойства и методы клосса называются членами класса.

Когда описывается переменная типа class, для ее полей и свойств в памяти выде-

ляется соответствующий объем (как и для записей), но машинный код, в который

транслируются методы класса, наличествует в единственном экземпляре, так как

меняться он не может, и хранить несколько одинаковых копий подпрограмм не

имеет смысла. Когда объект создается, однократно вызывается специальный метод,

называемый конструктором. В нем выполняются различные действия по началь-

ной инициализации полей объекта. Когда объект уничтожается (например, он был

описан внутри процедуры как локальная переменная и удаляется из памяти при

ее завершении), вызывается другой метод — деструктор, который выполняет раз-

личные дополнительные действия по освобождению памяти, если это необходимо.

Явно вызывать конструктор и деструктор из программного кода нельзя. Это про-

исходит только автоматически.

Переменная, описанная как класс, фактически является указателем на экземпляр

класса. Это сделано для повышения эффективности работы с ним. Однако при

исполюовании таких переменных применять операции работы с указателями (", @)

не надо. Достаточно обычного обращения к ним как к обычным переменным, а к

членам класса — как к полям записи, через точку.

ЗАМЕЧАНИЕ Описывать переменные, принадлежащие к типу class, внутри под-

программ в виде локальных типов не разрешается.__

Описание класса

Новый тип (класс) описывается в Паскале обычным способом, с помощью ключе-

вого слова class.

type имя-класса =

class(имя-родительского-класса)

список-членов-класса;

end;

Имя родительского класса указываегся, если новый класс должен наследовать все

его характеристики (и характеристики всех родителей этого класса). Исключать

какие-то члены родительских классов из наследования нельзя. Если имя родитель-

ского класса опустить:

type имя-класса =

class

список-членов-класса;

end;

то новый класс по умолчанию будет наследовать характеристики базового класса

TObject, который содержит встроенные конструктор, деструктор и общие свойства

и методы классов в среде Delphi, предназначен; 1ые для создания объекгов (экзем-

пляров класса), инициализации и освобождения памяти, и так далее. Корпорация

Inprise рекомендует всегда явно указывать базовый родительский класс TObject.

Б некоторых случаях возникает необходимость ввести в программу новый класс,

пока не описывая его структуру, а только определив заголовок (по аналогии с опи-

санием заголовка подпрограмм с ключевым словом forward). Эго допускается сде-

лать, просто указав название класса и ключевое слово class:

type TMyClass = class;

В дальнейшем, конечно, класс TMyCtass должен быть полностью определен.

Надо отличать такое предварительное упреждающее описание от реального описа-

ния класса следующего вида:

type TMyClass = class(TObject|;

Классы и объекты 87

Таким образом описывается полноценный класс TMyCtass, структурно совпадаю-

щий с классом TObject.

Список членов класса представляет собой список полей, свойств и методов, кото-

рые записываются как обычные поля записи или объявления подпрограмм в интер-

фейсном разделе, например:

type TMyClass = class

Count: Integer;

Name: String,-

procedure ShowMyClass(Dis: Boolean);

function GetCount: Integer;

end;

В классе TMyClass имеются два поля: Count и Name, — процедура ShowMyCLass (кото-

рая, возможно, показывает данный объект па экране) и функция GetCount, возвра-

щающая значение поля Count. Пока что поле Count доступно для изменения: по

умолчанию считается, что все члены класса не имеют никаких ограничений на ви-

димость.

ВНИМАНИЕ Описание полей и свойств в классе должно предшествовать описа-

нию методов.

Теперь в программу можно ввести новую переменную, представляющую собой

объект — экземпляр класса TMyCLass:

var MyClass: TMyClass;__

 

Пять уровней инкапсуляции

Доступность любых членов класса определяется принадлежностью к одному из

пяти уровней видимости класса, определяемых специальными ключевыми словами

Паскаля, которые разделяют описание класса на секции путем простого их указания

без дополнительных элементов типа точки с запятой. По умолчанию видимость

родительских членов класса наследуется в точности, однако разрешено повышать

видимость — делать поля, свойства и методы более доступными. Понижение види-

мости не допускается.

Раздел public. Члены класса, находящиеся в данном разделе, доступны из любой

точки программы.

type TMyClass = claae

public

Count: Integer;

Name: String;

procedure ShowMyClass(Dis: Boolean);

function GetCount: Integer;

end;

Раздел private. Этот раздел накладывает самые жесткие ограничения на видимость

указанных в нем членов класса. Они доступны только в том модуле, где данный

класс описан. Как правило, поля класса помещаются в эту секцию.

type TMyClass = class

private

Count: Integer;

Name: String;

Public

procedure ShowMyClass(Dis: Boolean);

function GetCount: Integer;

end;

По умолчанию считается, что все поля класса расположены в данном разделе.

Вышеприведенное описание аналогично следующему описанию (без ключевого

слова private).

type TMyClass = class

Count: Integer;

Name: String;

public

procedure ShowMyClasst Dis: Boolean),-

function GetCount: Integer;

end;

Раздел protected. Видимость членов класса, расположенных в этом разделе, совпа-

дает с видимостью раздела private с единственным отличием. Члены класса раздела

protected доступны также внутри методов классов, являющихся наследниками дан-

ного класса и описанных в других модулях.

Классы и обьекты 89

Раздел published. В этом разделе располагаются свойства класса: поля, доступные

для редактирования и изменения значений во время проектирования и из Инспектора

объектов. По видимости свойства не отличаются от членов классов, расположенных

в разделе public. Более подробно о свойствах и разделе published рассказывается в

главе, посвященной созданию собственных компонентов.

Раздел automated. Правила видимости членов раздела automated совпадают с пра-

вилами видимости для раздела public. Описания разрешается размещать в этом

разделе, только если класс является наследником стандартного класса TAutoObject, •

предназначенного для создания так называемых серверов автоматизации при исполь-

зовании технологии СОМ (см. соответствующую главу).

Присваивание объектов

Так Kajc класс — это обычный тип данных Паскаля, то переменным можно свобод-

но присваивать значения соответствующих объектов (реально копируются только

значения полей и свойств), причем как в точности своего типа, так и всех классов,

являющихся наследниками класса этой переменной.

Например, если в программе имеется следующее описание:

type Tl = class (TObject),-

Т2 = class(Tl);

var X: Tl;

TO в переменную X можно записывать как объекты типа Tl, так и объекты типа Т2.

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

полям записи, — указанием нужного поля или метода через точку.

var О: TMyClass;

О. Count:= 0;

О.Name:= 'Класс';

О.ShowMyClass(true);

Понятие свойства

Помимо полей и методов в объектах существуют свойства. При работе с объектом свойства выглядят как поля: они принимают значения и участвуют в выражениях. Но в отличие от полей свойства не занимают места в памяти, а операции их чтения и записи ассоциируются с обычными полями или методами. Это позволяет создавать необходимые сопутствующие эффекты при обращении к свойствам. Например, в объекте Reader присваивание свойству Active значения True вызовет открытие файла, а присваивание значения False — закрытие файла. Создание сопутствующего эффекта (открытие или закрытие файла) достигается тем, что за присваиванием свойству значения стоит вызов метода.

Объявление свойства выполняется с помощью зарезервированного слова property, например:

type TDelimitedReader = class... FActive: Boolean;... // Метод записи (установки значения) свойства procedure SetActive(const AActive: Boolean); property Active: Boolean read FActive write SetActive; // Свойство end;

 

Ключевые слова read и write называются спецификаторами доступа. После слова read указывается поле или метод, к которому происходит обращение при чтении (получении) значения свойства, а после слова write — поле или метод, к которому происходит обращение при записи (установке) значения свойства. Например, чтение свойства Active означает чтение поля FActive, а установка свойства — вызов метода SetActive. Чтобы имена свойств не совпадали с именами полей, последние принято писать с буквы F (от англ. field). Мы в дальнейшем также будем пользоваться этим соглашением. Начнем с того, что переименуем поля класса TDelimitedReader: поле FileVar переименуем в FFile, Items — в FItems, а поле Delimiter — в FDelimiter.

type TDelimitedReader = class // Поля FFile: TextFile; // FileVar -> FFile FItems: array of string; // Items -> FItems FActive: Boolean; FDelimiter: Char; // Delimiter -> FDelimiter... end;

 

Обращение к свойствам выглядит в программе как обращение к полям:

var Reader: TDelimitedReader; IsOpen: Boolean;... Reader.Active:= True; // Эквивалентно Reader.SetActive(True); IsOpen:= Reader.Active; // Эквивалентно IsOpen:= Reader.FActive

 

Если один из спецификаторов доступа опущен, то значение свойства можно либо только читать (задан спецификатор read), либо только записывать (задан спецификатор write). В следующем примере объявлено свойство, значение которого можно только читать.

type TDelimitedReader = class... FItems: array of string;... function GetItemCount: Integer;... property ItemCount: Integer read GetItemCount; // Только для чтения! end; function TDelimitedReader.GetItemCount: Integer;begin Result:= Length(FItems);end;

 

Здесь свойство ItemCount показывает количество элементов в массиве FItems. Поскольку оно определяется в результате чтения и разбора очередной строки файла, пользователю объекта разрешено лишь узнавать количество элементов.

В отличие от полей свойства не имеют адреса в памяти, поэтому к ним запрещено применять операцию @. Как следствие, их нельзя передавать в var - и out -параметрах процедур и функций.

Технология объектно-ориентированного программирования в среде Delphi предписывает избегать прямого обращения к полям, создавая вместо этого соответствующие свойства. Это упорядочивает работу с объектами, изолируя их данные от непосредственной модификации. В будущем внутренняя структура класса, которая иногда является достаточно сложной, может быть изменена с целью повышения эффективности работы программы. При этом потребуется переработать только методы чтения и записи значений свойств; внешний интерфейс класса не изменится.



Поделиться:


Последнее изменение этой страницы: 2017-02-21; просмотров: 508; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.190.156.80 (0.024 с.)