是否可以使用在接口部分的实现部分中声明的类
如果我理解正确,该interface部分对其他单位可见,并且该implementation部分仅在当前.pas文件中可见。
我有两个类,类TA应该对外可见,其他类TB不应该,但我需要一个类型为TBin的字段TA。
interface
type
TA = class
//something
B : TB;
end;
//something
implementation
type
TB = class
//something
end;
它不是那样工作的。我也不能使用前向声明。有办法吗?
或者,是否有一种方法可以TB在该interface部分中声明但使其具有某种私有性?
回答
类型在声明之前不能使用(就行号而言)。特别是,这意味着您不能使用在implementation节中的interface节中声明的类型。
但是,请考虑以下示例:
unit VisibilityTest;
interface
type
TFrog = class
strict private type
TFrogMetabolism = class
procedure DoAnabolismStuff;
procedure DoCatabolismStuff;
end;
strict private
FMetabolism: TFrogMetabolism;
public
procedure Croak;
procedure Walk;
procedure Jump;
end;
implementation
{ TFrog.TFrogMetabolism }
procedure TFrog.TFrogMetabolism.DoAnabolismStuff;
begin
end;
procedure TFrog.TFrogMetabolism.DoCatabolismStuff;
begin
end;
{ TFrog }
procedure TFrog.Jump;
begin
end;
procedure TFrog.Croak;
begin
end;
procedure TFrog.Walk;
begin
end;
end.
在这里,TFrog类是给其他单位,以及其明显的Croak,Walk和Jump方法。
并且它确实有一个(strict private在这个例子中)类型的字段,由于前面的规范TFrogMetabolism,这个类型只能在内部使用TFrog——因此只能在这个单元内部使用strict private。
这应该会给你一些想法。一些变体是可能的:
-
如果
strict从 中删除strict private type,则TFrogMetabolism该类可以在此特定单元内的任何地方使用,而不仅仅是在TFrog. -
如果替换
private为protected,则该类也可用于不是TFrog但派生自 的类中TFrog。
回答
你可以做到,但要付出代价。在 TA 类中,引用 TB 的变量必须是 TObject 类型。让我们将该变量命名为 B。您可以将类 TB 的一个实例分配给该变量,例如从构造函数中。然后当 TA 中的代码需要使用变量 B 时,它必须强制转换为 TB(硬转换或使用“As”运算符)。
您还应该禁用该 TB 上的 RTTI,以便外部无法发现 TB 内部的内容。
这是代码:
unit Unit24;
interface
uses
System.SysUtils;
type
TA = class
B : TObject; // Will contain a TB instance
constructor Create;
destructor Destroy; override;
procedure Demo;
end;
implementation
type
TB = class
procedure SayHello;
end;
{ TA }
constructor TA.Create;
begin
inherited Create;
B := TB.Create;
end;
procedure TA.Demo;
begin
TB(B).SayHello;
end;
destructor TA.Destroy;
begin
FreeAndNil(B);
inherited Destroy;
end;
{ TB }
procedure TB.SayHello;
begin
WriteLn('Hello!');
end;
end.
使用示例:
program Project24;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Unit24 in 'Unit24.pas';
var
A : TA;
begin
A := TA.Create;
try
A.Demo;
finally
A.Free;
end;
end.