При работе с объектно-ориентированным программированием в Delphi важно понимать концепцию приватности методов и свойств классов. В Delphi 7 есть особенности, которые могут вводить в заблуждение разработчиков, особенно когда речь идет о приватности методов внутри одного модуля.
Проблема
В коде ниже показана ситуация, когда приватная процедура one класса tmyclass вызывается из метода Button1Click формы TForm1, что не должно быть возможно, если понимать приватность как полную изоляцию.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
tmyclass = class
private
procedure one;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure tmyclass.one;
begin
ShowMessage('1');
end;
procedure TForm1.Button1Click(Sender: TObject);
var myclass: tmyclass;
begin
myclass.one;
end;
end.
Решение
В Delphi 7 классы, объявленные в одном и том же модуле, имеют неявный доступ друг к другу, что означает, что они могут обращаться к приватным и защищенным членам друг друга. Это поведение изменилось с введением директив strict private и strict protected в Delphi 8.
Чтобы убедиться, что приватные процедуры действительно не доступны, необходимо переместить класс tmyclass в отдельный модуль и использовать его в модуле с формой. Таким образом, приватные процедуры станут недоступными для вызова из других модулей.
Пример
Создадим два модуля: UnitMyClass и UnitMain.
UnitMyClass.dpr:
unit UnitMyClass;
interface
type
tmyclass = class
private
procedure one;
public
constructor Create; override;
end;
implementation
constructor tmyclass.Create;
begin
inherited Create;
end;
procedure tmyclass.one;
begin
ShowMessage('1');
end;
end.
UnitMain.dpr:
unit UnitMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, UnitMyClass;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var myclass: tmyclass;
begin
myclass := tmyclass.Create;
try
myclass.one; // Теперь это вызов вызовет ошибку, так как myclass и TForm1 находятся в разных модулях
finally
myclass.Free;
end;
end;
end.
Теперь, когда tmyclass находится в отдельном модуле, попытка вызова myclass.one из Button1Click приведет к ошибке, поскольку приватные методы класса tmyclass не будут доступны из модуля UnitMain.
Заключение
В Delphi 7 неявный доступ к приватным членам классов в пределах одного модуля может привести к неожиданному поведению. Чтобы гарантировать приватность, следует разделить классы по модулям или использовать директивы strict private и strict protected, доступные в более новых версиях Delphi.
В Delphi 7 для обеспечения приватности процедур необходимо разместить класс с этими процедурами в отдельном модуле, чтобы предотвратить нежелательный доступ к приватным членам из других модулей.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.