Области видимости элементов классов Delphi | Way23

Области видимости элементов классов 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.
1
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.
1
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;
1
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.
1
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.
1
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.
1
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.
1
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.

Ссылки

Последниее изменение: 03.04.2022, 12:50:42