Delphi:如何将类移出单元;避免循环引用
问题:我想将两个类拆分到它们自己的文件中,同时避免循环引用。
我有一个包含一些类(以及一些枚举和常量)的单元。任何人都会认识Click and Clack the tappet brothers:
unit Cartalk;
interface
type
TSolution = (solTransmission, solBrakes, solGremlins);
TTappetBrother = class(TObject)
public
function GetSolution: TSolution; virtual; abstract;
end;
TClick = class(TTappetBrother)
public
function GetSolution: TSolution; override;
end;
TClack = class(TTapperBrother)
public
function GetSolution: TSolution; override;
end;
implementation
function TClick.GetSolution: TSolution;
begin
Result := solTransmission;
end;
function TClack.GetSoltution: TSolution;
begin
Result := solGremlins;
end;
end.
现在显然是我的两个类TClick
和TClick
相当复杂。为了便于管理,我想将 TClick
和 TClack
拆分为它们自己的单元同时不破坏任何现有的外部代码。
我的第一个破解是:
unit Cartalk;
interface
uses
Cartalk_Click, Cartalk_Clack;
type
TSolution = (solTransmission, solBrakes, solGremlins);
TTappetBrother = class(TObject)
public
function GetSolution: TSolution; virtual; abstract;
end;
TClick = Cartalk_Click.TClick; //alias brought in from Cartalk_Click.pas
TClack = Cartalk_Clack.TClack; //alias brought in from Cartalk_Clack.pas
implementation
end.
完美,我在 Cartalk.pas
中提供了所有相同的类,现在我只需要编写 Cartalk_Click.pas
和 Cartalk_Clack .pas
:
unit Cartalk_Click;
interface
type
TClick = class(TTappetBrother)
public
function GetSolution: TSolution; override;
end;
implementation
function TClick.GetSolution: TSolution;
begin
Result := solTransmission;
end;
end.
问题当然是 TTappetBrother
和 TSolution
没有在这个单元中声明。因此,我们向 uses
添加对它们所在位置的引用,观察它失败,并触及我问题的核心:
unit Cartalk_Click;
interface
uses
Cartalk;
type
TClick = class(TTappetBrother)
public
function GetSolution: TSolution; override;
end;
implementation
function TClick.GetSolution: TSolution;
begin
Result := solTransmission;
end;
end.
现在 Cartalk
和 之间存在循环引用>Cartalk_Click
。
注意: 当然,我没有 Cartalk 装置,还有 Click 和 Clack the tapper brothers - 这只是一个例子。实际上,我的单元中有 3 个类、20 个枚举和 293 个常量。
Question: i want to split two classes out to their own file, while avoiding circular references.
i have a unit with some classes (and some enumerations and constants). Anyone will recognize Click and Clack the tappet brothers:
unit Cartalk;
interface
type
TSolution = (solTransmission, solBrakes, solGremlins);
TTappetBrother = class(TObject)
public
function GetSolution: TSolution; virtual; abstract;
end;
TClick = class(TTappetBrother)
public
function GetSolution: TSolution; override;
end;
TClack = class(TTapperBrother)
public
function GetSolution: TSolution; override;
end;
implementation
function TClick.GetSolution: TSolution;
begin
Result := solTransmission;
end;
function TClack.GetSoltution: TSolution;
begin
Result := solGremlins;
end;
end.
Now obviously my two classes TClick
and TClick
are quite complex. For manageability i'd like to split TClick
and TClack
out to their own units while not breaking any existing external code.
My first crack at it would be:
unit Cartalk;
interface
uses
Cartalk_Click, Cartalk_Clack;
type
TSolution = (solTransmission, solBrakes, solGremlins);
TTappetBrother = class(TObject)
public
function GetSolution: TSolution; virtual; abstract;
end;
TClick = Cartalk_Click.TClick; //alias brought in from Cartalk_Click.pas
TClack = Cartalk_Clack.TClack; //alias brought in from Cartalk_Clack.pas
implementation
end.
Perfect, i have all the same classes available in Cartalk.pas
, now i just have to write Cartalk_Click.pas
and Cartalk_Clack.pas
:
unit Cartalk_Click;
interface
type
TClick = class(TTappetBrother)
public
function GetSolution: TSolution; override;
end;
implementation
function TClick.GetSolution: TSolution;
begin
Result := solTransmission;
end;
end.
Problem, of course, is that TTappetBrother
and TSolution
are not declared in this unit. So we add a reference to where they live to the uses
, watch it fail, and reach the heart of my question:
unit Cartalk_Click;
interface
uses
Cartalk;
type
TClick = class(TTappetBrother)
public
function GetSolution: TSolution; override;
end;
implementation
function TClick.GetSolution: TSolution;
begin
Result := solTransmission;
end;
end.
There is now a circular reference between Cartalk
and Cartalk_Click
.
Note: Of course i don't have a Cartalk unit, with Click and Clack the tapper brothers - this is just an example. In reality i have 3 classes, 20 enumerations, and 293 constants in my unit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编写一个单元:
并在
Click
和Clack
单元中使用它。然后编写CarTalk
单元以使用所有这三个并在其接口中导出所需的类型。不需要循环引用。Write a unit:
and use it in the
Click
and theClack
units. Then write theCarTalk
unit to use all three and export the needed types in its interface. No circular references needed.