问题
I'm trying to check if my private procedures are really private. But it works the way it shouldn't.
Please help me, maybe I missed something about how the incapsulation should work.
This code should not work. I guess. But it works.
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.
Thank you. (Delphi-7, Win7 x64).
回答1:
private
is for a unit
.
With more recent version of Delphi, you can use strict private
to get the expected behavior.
回答2:
The meaning of private
is clearly documented:
Private, Protected, and Public Members
A private member is invisible outside of the unit or program where its class is declared. In other words, a private method cannot be called from another module, and a private field or property cannot be read or written to from another module. By placing related class declarations in the same module, you can give the classes access to one another's private members without making those members more widely accessible. For a member to be visible only inside its class, it needs to be declared strict private.
A protected member is visible anywhere in the module where its class is declared and from any descendent class, regardless of the module where the descendent class appears. A protected method can be called, and a protected field or property read or written to, from the definition of any method belonging to a class that descends from the one where the protected member is declared. Members that are intended for use only in the implementation of derived classes are usually protected.
A public member is visible wherever its class can be referenced.
Strict Visibility Specifiers
In addition to private and protected visibility specifiers, the Delphi compiler supports additional visibility settings with greater access constraints. These settings are strict private and strict protected visibility. These settings can be used in Win32 applications.
Class members with strict private visibility are accessible only within the class in which they are declared. They are not visible to procedures or functions declared within the same unit. Class members with strict protected visibility are visible within the class in which they are declared, and within any descendent class, regardless of where it is declared. Furthermore, when instance members (those declared without the class or class var keywords) are declared strict private or strict protected, they are inaccessible outside of the instance of a class in which they appear. An instance of a class cannot access strict protected or strict protected instance members in other instances of the same class.
Delphi's traditional private visibility specifier maps to the CLR's assembly visibility. Delphi's protected visibility specifier maps to the CLR's assembly or family visibility.
Note: The word strict is treated as a directive within the context of a class declaration. Within a class declaration you cannot declare a member named 'strict', but it is acceptable for use outside of a class declaration.
Your version of Delphi, Delphi 7, does not support the strict
specifiers.
回答3:
Here are two sample units to show the visibility of private
, protected
and public
parts from a class.
unit BaseClass;
interface
type
TBaseClass0 = class
strict private
FStrictPrivate : Integer;
private
FPrivate : Integer;
strict protected
FStrictProtected : Integer;
protected
FProtected : Integer;
public
FPublic : Integer;
procedure DoSomeThing; virtual;
end;
TBaseClass1 = class( TBaseClass0 )
public
procedure DoSomeThing; override;
end;
procedure DoSomeThing( ABase : TBaseClass0 );
implementation
{ TBaseClass0 }
procedure TBaseClass0.DoSomeThing;
begin
FStrictPrivate := 0;
FPrivate := 0;
FStrictProtected := 0;
FProtected := 0;
FPublic := 0;
end;
{ TBaseClass1 }
procedure TBaseClass1.DoSomeThing;
begin
inherited;
// FStrictPrivate := 1; // no access
FPrivate := 1;
FStrictProtected := 1;
FProtected := 1;
FPublic := 1;
end;
procedure DoSomeThing( ABase : TBaseClass0 );
begin
with ABase do
begin
// FStrictPrivate := 3; // no access
FPrivate := 3;
// FStrictProtected := 3; // no access
FProtected := 3;
FPublic := 3;
end;
end;
end.
unit BaseClass2;
interface
uses
BaseClass;
type
TBaseClass2 = class( TBaseClass0 )
public
procedure DoSomeThing; override;
end;
procedure DoSomeThing( ABase : TBaseClass0 );
implementation
{ TBaseClass2 }
procedure TBaseClass2.DoSomeThing;
begin
inherited;
// FStrictPrivate := 2; // no access
// FPrivate := 2; // no access
FStrictProtected := 2;
FProtected := 2;
FPublic := 2;
end;
procedure DoSomeThing( ABase : TBaseClass0 );
begin
with ABase do
begin
// FStrictPrivate := 4; // no access
// FPrivate := 4; // no access
// FStrictProtected := 4; // no access
// FProtected := 4; // no access
FPublic := 4;
end;
end;
end.
来源:https://stackoverflow.com/questions/16554781/delphi-private-clause-directive-does-not-work