6.1 Определения классов

Вверх  Предыдущий  Следующий

Класс определяется следующим образом:


Тип класса

601


Примечание:

В режиме MacPas, ключевое слово Object заменяется ключевым словом class для совместимости с другими Pascal компиляторами, имеющихся на Mac. Это означает, что в режиме MacPas, зарезервированное слово class (класс) на рисунке выше, может быть заменено зарезервированным словом object (объект).

В объявлении класса, так как многие private (частные), protected (защищенные), published (опубликованые) и public (публичные) блоки  могут быть использованы по мере необходимости: различные блоки можно повторять, и нет специального порядка, в котором они должны появляться.

Методы являются обычными декларациями функций или процедур. Как видно, объявление класса практически идентично декларации объекта. Реальная разница между объектами и классами заключается в способе их создания (см далее в этой главе).

Видимость различных разделов выглядит следующим образом:

Private
Все поля и методы, из раздела private, могут быть доступны только в модуле (т.е. unit-е), который содержит определение класса. Они могут быть доступны внутри методов класса или из за их пределами (например, в других методах класса).

Strict Private
Все поля и методы, которые из раздела strict private, могут быть доступны только из методов самого класса. Другие классы или классы-потомки (даже в том же модуле) не могут получить доступ к strict private членам.

Protected
То же самое, что и private, кроме того,  члены из раздела protected также доступны для потомком типа, даже если они используются в других модулях.

Public
раздел всегда доступен.

Published
То же самое, как в разделе public, но компилятор генерирует также информацию, необходимую для автоматического сохранения в потоке этих полей для этого класса, если компилятор в {$M+} состояния. Поля, определенные в разделе published должен быть типа класса. Свойства массива не могут быть в разделе published.

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

Классы могут содержать Class methods (методы класса): это функции, которые не требуют экземпляра. Идентификатор Self действует в таких методах, но относится к самому классу указателя (на VMT класса).

Примечание:

Как в функциях и указателях на типы, иногда необходимы forward (предварительные) определение класса. Предварительное определение класса - просто название класса, с ключевым словом Class, как показано в следующем примере:

Type

 TClassB = Class;

 TClassA = Class

   B : TClassB;

end;

 TClassB = Class

   A : TClassA;

end;

При использовании предварительного определения класса, класс должен быть определен в том же блоке, в том же разделе (interface/implementation) (интерфейс/реализация). Но не обязательно должен быть определен в том же разделе type.

Кроме того, можно определить опорные классы:


Тип Опорный класс

602


Тип опорного класса используются для создания экземпляров определенного класса, который пока не известен во время компиляции, но который указан во время выполнения. По сути, переменная ссылочного класса типа содержит указатель на  определению указанного класса. Это может быть использовано для создания экземпляра класса, соответствующего определению, или проверить наследство. Следующий пример показывает, как это работает:

Type

TComponentClass = Class of TComponent;

Function CreateComponent(AClass: TComponentClass; AOwner: TComponent): TComponent;

begin

// ...

Result:=AClass.Create(AOwner);

// ...

end;

Этой функции может быть передана ссылка на класс любого класса, который наследуется от TComponent.  Вызов ниже является допустимым:

Var

C : TComponent;

begin

C:=CreateComponent(TEdit,Form1);

end;

При вызове функции CreateComponent, C будет содержать экземпляр класса TEdit. Обратите внимание, что следующий вызов не будет компилироваться:

Var

C : TComponent;

begin

C:=CreateComponent(TStream,Form1);

end;

потому что TStream не наследуется от TComponent, и AClass относится к классу TComponent. Компилятор  проверит это во время компиляции, и выдаст ошибку.

Ссылки на классы также могут быть использованы для проверки наследования:

TMinClass = Class of TMyClass;

TMaxClass = Class of TMyClassChild;

 

Function CheckObjectBetween(Instance : TObject) : boolean;

begin

If not (Instance is TMinClass) or ((Instance is TMaxClass)

        and (Instance.ClassType<>TMaxClass)) then

                Raise Exception.Create(SomeError)

end;

Приведенный выше пример вызовет исключение, если экземпляр не является потомком TMinClass или является потомком TMaxClass.

Подробнее о экземпляре класса можно найти в следующем разделе 6.3 Экземпляр класса