Ламер обращается к компьютеру на "Вы", юзер - на "Ты", а хакер - на "Ты козел".
unit TestClass;
interfacetype
TTest = classprotected
ProtectedData: Integer;
public
PublicData: Integer;
function GetValue: string;
end;
implementationuses
SysUtils;
function TTest.GetValue: string;
begin
Result := Format ('Public: %d, Protected: %d',
[PublicData, ProtectedData]);
end;
end.
unit ProtForm;
interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private{ Private declarations }public{ Public declarations }end;
var
Form1: TForm1;
implementation{$R *.DFM}uses
TestClass;
procedure TForm1.Button1Click(Sender: TObject);
var
Obj: TTest;
begin
Obj := TTest.Create;
Obj.PublicData := 10;
// Obj.ProtectedData := 20; //won't compile
ShowMessage (Obj.GetValue);
Obj.Free;
end;
type
TFake = class (TTest);
procedure TForm1.Button2Click(Sender: TObject);
var
Obj: TTest;
begin
Obj := TTest.Create;
Obj.PublicData := 10;
TFake (Obj).ProtectedData := 20; // compiles!
ShowMessage (Obj.GetValue);
Obj.Free;
end;
end.
Проблема заключается в том, что класс TTest имеет защищенный свойство ProtectedData, которое не может быть доступно напрямую из экземпляра TTest. Это потому, что оно помечено как protected, что означает, что оно может быть доступно только внутри самого класса или его производных.
В первом процедедуре, когда вы пытаетесь установить Obj.ProtectedData := 20; , компилятор не позволяет это сделать, потому что это запрещено.
Однако, во втором процедедуре, вы создаете новый класс TFake, который наследуется от TTest. Поскольку TFake является производным классом от TTest, он может доступаться к защищенным членам TTest, включая ProtectedData.
Чтобы решить это без создания отдельного класса, как TFake, вы можете сделать свойство ProtectedData публичным в классе TTest. Однако, сделав его публичным, вы делаете его доступным из любого места, что может не быть тем, что вы хотите.
unitProtForm;interfaceusesWindows,Messages,SysUtils,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls;typeTForm1=class(TForm)Button1:TButton;Button2:TButton;procedureButton1Click(Sender:TObject);procedureButton2Click(Sender:TObject);private{ Private declarations }public{ Public declarations }end;varForm1:TForm1;implementation{$R *.DFM}usesTestClass;procedureTForm1.Button1Click(Sender:TObject);varObj:TTest;beginObj:=TTest.Create;Obj.PublicData:=10;Obj.ProtectedData:=20;// теперь компиляция проходит!ShowMessage(Obj.GetValue);Obj.Free;end;procedureTForm1.Button2Click(Sender:TObject);varObj:TTest;beginObj:=TTest.Create;Obj.PublicData:=10;// TFake(Obj).ProtectedData := 20; // теперь не нужноShowMessage(Obj.GetValue);Obj.Free;end;end.
Теперь вы можете доступаться к свойству ProtectedData напрямую из экземпляра TTest.
В статье описывается, как в Delphi присваивать значение защищённому свойству класса, используя наследование или создание интерфейса для доступа к защищенным свойствам.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.