«Очень важно не прерывать вопросов. Любопытство имеет свое право на существование»
24. Поля и методы классов
Поля (Fields).
Поле подобно переменной, которая принадлежит классу. Поля могут иметь любой тип, включая классы. Это, в частности, значит, что поле может быть ссылкой на объект. Поля обычно являются личными (private).
Все объявления полей должны предшествовать объявлениям свойств или методов. Например, следующее описание является описанием класса TNumber, единственным полем которого является Int.
type TNumber = class
Int: Integer;
end;
Поля являются статическими в том смысле, что ссылки на них разрешаются на этапе компиляции. Для уяснения следствий из этого факта, проанализируйте следующий код:
type
TAncestor = class
Value: Integer;
end;
TDescendant = class(TAncestor)
Value: string; // скрывает унаследованное поле
end;
. . .
var
MyObject: TAncestor;
begin
MyObject := TDescendant.Create; // внимание !
MyObject.Value := 'Hello!'; // ошибка
TDescendant(MyObject).Value := 'Hello!'; // работает
end;
Хотя MyObject является экземпляром TDescendant, он объявлен как имеющий тип TAncestor. По этой причине компилятор интерпретирует MyObject.Value как ссылку на целочисленное поле, объявленное в классе TAncestor. Оба поля, тем не менее, существуют в объекте TDescendant и унаследованное поле Value перекрывается новым полем, доступ к которому возможен с помощью приведения типа.
Методы (Methods).
Метод – это процедура или функция, ассоциированная с классом. Вызов метода специфирует также объект (или класс, если метод является методом класса), для которого вызывается метод. Например, SomeObject.Free вызывает метод Free объекта SomeObject.
Реализация методов (Method implementations).
Внутри описания класса метод появляется как заголовок процедуры или функции, который является аналогом опережающего описания. Где-либо после описания класса, однако в том же модуле, для каждого метода должно быть дано определяющее описание. Предположим, что описание TMyClass включает метод DoSomething:
type
TMyClass = class(TObject)
…
procedure DoSomething;
…
end;
Определяющее описание DoSomething должно быть сделано позже в модуле:
procedure TMyClass.DoSomething;
begin
…
end;
В то время как описание класса может быть сделано в интерфейсной секции модуля или в секции реализации, описания классов должны быть сделаны в секции реализации.
В определяющем описании имя метода должно быть уточнено именем класса, которому он принадлежит. Заголовок метода может повторять описания формальных параметров из описания класса и в этом случае эти описания должны быть полностью идентичными.
Замечание. В Delphi заготовку метода удобно генерировать с помощью команды Shift+Ctrl+C контекстного меню. |
Зарезервированное слово Inherited (унаследованный).
Это слово играет специальную роль в реализации преимуществ полиморфизма. Оно может быть указано в теле метода, сопровождаемое идентификатором или без него.
Если после inherited указан идентификатор, это обозначает обычный вызов метода за тем исключением, что поиск метода начинается с класса, являющегося непосредственным родительским классом данному. Например, когда вызов
inherited Create;
встречается в теле метода, он обозначает вызов унаследованного метода Create.
Когда же слово inherited не сопровождается идентификатором, оно ссылается на метод с тем же именем, что и описываемый метод. В этом случае inherited может появиться со списком фактических параметров или без него. Если параметры не указаны, то вызываемому методу передаются те же параметры, с которыми вызван описываемый метод. Например, оператор
inherited;
часто встречается в описаниях конструкторов и вызывает унаследованный конструктор с теми же параметрами, что и описываемый.
Идентификатор Self.
В теле метода этот идентификатор ссылается на объект, для которого вызван метод. Вот пример описания метода Add класса TCollection модуля Classes библиотеки VCL.
function TCollection.Add: TCollectionItem;
begin
Result := FItemClass.Create(Self);
end;
Метод Add вызывает метод Create класса, на который указывает поле FItemClass, которое всегда является наследником TCollectionItem. Метод TCollectionItem.Create требует единственный параметр типа TCollection, поэтому Add передает экземпляр класса (объект), для которого он вызван.
Этот факт иллюстрируется следующим кодом:
var MyCollection: TCollection;
…
MyCollection.Add // Объект MyCollection передается методу TCollectionItem.Create
Идентификатор Selfполезен во многих отношениях. Например, идентификатор компонента, объявленного в классе, может быть перекрыт в описании метода. В этом случае можно получить доступ к оригинальному компоненту с помощью уточненного идентификатора Self.Identifier, например:
TMyClass = class
public
Num : integer;
Procedure SetNumB(Num:integer);
end;
// …
procedure TMyClass.SetNumB(Num:integer);
begin
Self.Num:=Num;
end;
«23. Видимость компонентов класса»
25. Связывание методов