Области видимости объектов.

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

Поля, свойства и методы доступны:

public, published — всем и везде, в том числе в других модулях;

protected — только в описании методов в классах потомков (в том числе в других модулях);

private — только в процедурах и функциях модуля, где описывается данный класс, а также в методах классов потомков, определенных внутри этого модуля.

Разновидностью public является published. "Опубликованные" поля, методы и свойства доступны в интерфейсе визуального проектирования Delphi (в инспекторе объектов) на стадии разработки. В первых версиях Delphi действовало правило, что если в описании класса были опущены ключевые слова для определения правил видимости, считалось, что соответствующие методы, поля и свойства published. Начиная с Delphi 3.0 область видимости объекта "published" также должна быть явно описана. Т.е. во всех примерах, где мы работали с классами, надо поставить директиву public или published перед описанием полей и методов объекта. Например:

tMyObj1=class(tObj1)

...

end;

заменить на

tMyObj1=class(tObj1)

public

...

end;

Пример правил видимости внутри модуля:

unit vis1;

interface

type

tObj1=

class

public

procedure MyPublicMethod;

...

protected

procedure MyProtectedMethod;

...

private

procedure MyPrivateMethod;

...

end;

procedure MyProc1; {процедура, видимая в других модулях}

...

{-секция реализации-}

implementation

... {реализация tObj1.MyPublicMethod, tObj1.MyProtectedMethod,

tObj1.MyPrivateMethod}

...

...

var aObj1:tObj1;

procedure MyProc1;

begin

aObj1:=tObj1.Create;

aObj1.MyPublicMethod; {можно}

{aObj1.MyProtectedMethod; -нельзя, т.к. не описание метода в

классе–наследнике}

aObj1.MyPrivateMethod; {можно, т.к. тот же модуль}

aObj1.Free; {то же, что Destroy, но с проверкой на nil}

end; {/MyProc1}

end. {/implementation}

Правила видимости в другом модуле:

unit vis2;

interface

uses vis1;

type

tObj2=

class(tObj1)

procedure MethodOfNewClass; {определение метода в потомке}

end;

procedure MyProc2; {процедура, видимая в других модулях}

{-секция реализации-}

implementation

procedure tObj2.MethodOfNewClass;

begin

MyPublicMethod; {можно, т.к. Public метод}

MyProtectedMethod; {можно, т.к. описание метода в

классе - наследнике}

{MyPrivateMethod; -нельзя, т.к. другой модуль}

end;

var aObj2:tObj2; {реализация}

procedure MyProc2;

begin

aObj2:=tObj2.Create;

aObj2.MyPublicMethod; {можно, т.к. public}

{aObj2.MyProtectedMethod; -нельзя, т.к. не описание метода

в классе - наследнике}

{aObj2.MyPrivateMethod; -нельзя, т.к. другой модуль}

aObj2.Free;

end;

end.

При описании класса-наследника можно переносить методы и свойства из одной области видимости в другую путем их простого упоминания, без переписывания реализации и сигнатуры:

type

tObj1=

class

private

fMyData:Real;

protected

function GetMyData:Real;

property MyData:Real

read GetMyData;

...

end{/class};

tObj2=

class(tObj1)

public

property MyData;

...

end{/class};

Замечание:

1) Из областей private в потомках в других модулях ничего достать, естественно, нельзя, хотя соответствующие поля и методы наследуются.

2) Иногда удобно перемещать поля или методы потомков из видимых областей в protected или private, иногда — наоборот (если это допустимо правилами прозрачности).