Области видимости элементов классов Delphi
Для контроля доступа к полям, методам и свойствам классов используются области видимости. В Delphi есть следующие области видимости:
- public
- published
- strict private
- private
- strict protected
- protected
Рассмотрим их на примерах.
public
Элементы секции public не имеют ограничений доступа. Они доступны отовсюду: из методов своего класса, из методов других классов, из своего модуля и из других модулей.
unit uCircle;
interface
type
TCircle = class
public
FRadius: Integer;
function Area: Extended;
end;
implementation
{ TCircle }
function TCircle.Area: Extended;
begin
Result := FRadius * FRadius * Pi; // Поле доступно внутри класса
end;
end.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
unit uCheckCircle;
interface
procedure CheckCircle;
implementation
uses
System.SysUtils,
Vcl.Dialogs,
uCircle;
procedure CheckCircle;
var
Circle: TCircle;
begin
Circle := TCircle.Create;
try
Circle.FRadius := 2; // Поле доступно снаружи
ShowMessage(FloatToStr(Circle.FRadius));
finally
FreeAndNil(Circle);
end;
end;
end.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
uses
uCheckCircle;
procedure TForm1.Button1Click(Sender: TObject);
begin
CheckCircle;
end;
2
3
4
5
6
7
published
Видимость элементов в секции published полностью аналогична секции public. В этом посте рассматривается только поведение касающееся видимости, подробнее в различиях связанных с RTTI описано в документацииopen in new window.
Область по умолчанию
Если не указывать область видимости то она будет аналогичной области public.
unit uCircle;
interface
type
TCircle = class
FRadius: Integer;
function Area: Extended;
end;
implementation
{ TCircle }
function TCircle.Area: Extended;
begin
Result := FRadius * FRadius * Pi; // Поле доступно внутри класса
end;
end.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Аналогично поле видно и из других модулей.
strict private
Самая ограниченная область видимости. Элементы в секции private доступны только из методов класса. К ним нет доступа из методов других объектов, независимо от модуля в котором они находятся. Также к ним нет доступа из наследников данного объекта.
unit uCircle;
interface
type
TCircle = class
strict private
FRadius: Integer;
public
function Area: Extended;
end;
procedure CheckCircle;
implementation
uses
System.SysUtils,
Vcl.Dialogs;
{ TCircle }
function TCircle.Area: Extended;
begin
Result := FRadius * FRadius * Pi; // Поле доступно внутри класса
end;
procedure CheckCircle;
var
Circle: TCircle;
begin
Circle := TCircle.Create;
try
Circle.FRadius := 2; // ошибка компиляции
ShowMessage(FloatToStr(Circle.FRadius));
finally
FreeAndNil(Circle);
end;
end;
end.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private
Секция private совпадает с секцией strict private, за исключением того что все элементы этой секции доступны из любого метода любого класса в том же модуле в котором объявлен класс.
unit uCircle;
interface
type
TCircle = class
private
FRadius: Integer;
public
function Area: Extended;
end;
procedure CheckCircle;
implementation
uses
System.SysUtils,
Vcl.Dialogs;
{ TCircle }
function TCircle.Area: Extended;
begin
Result := FRadius * FRadius * Pi; // Поле доступно внутри класса
end;
procedure CheckCircle;
var
Circle: TCircle;
begin
Circle := TCircle.Create;
try
Circle.FRadius := 2; // работает
ShowMessage(FloatToStr(Circle.FRadius));
finally
FreeAndNil(Circle);
end;
end;
end.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Если перенести процедуру CheckCircle
в другой модуль то произойдёт ошибка компиляции, так как FRadius
уже будет недоступен.
strict protected
Элементы объявленные с секции strict protected доступны только из методов самого класса и из классов потомков. От модуля в котором они находятся это не зависит.
unit uCircle;
interface
type
TCircle = class
strict protected
FRadius: Integer;
public
function Area: Extended;
end;
TSuperCircle = class(TCircle)
public
function Diameter: Extended;
end;
procedure CheckCircle;
implementation
uses
System.SysUtils,
Vcl.Dialogs;
{ TCircle }
function TCircle.Area: Extended;
begin
Result := FRadius * FRadius * Pi; // Поле доступно внутри класса
end;
{ TSuperCircle }
function TSuperCircle.Diameter: Extended;
begin
Result := FRadius * 2; // Поле доступно в потомке
end;
procedure CheckCircle;
var
Circle: TCircle;
begin
Circle := TCircle.Create;
try
Circle.FRadius := 2; // но вне класса также недоступно
ShowMessage(FloatToStr(Circle.FRadius));
finally
FreeAndNil(Circle);
end;
end;
end.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
protected
Секция protected совпадает с секцией strict protected, за исключением того что все элементы этой секции доступны из любого метода в том же модуле в котором объявлен класс. Ситуация аналогичная private и strict private.