Delphi:如何将类移出单元;避免循环引用

发布于 2024-09-28 05:13:45 字数 2487 浏览 1 评论 0原文

问题:我想将两个类拆分到它们自己的文件中,同时避免循环引用。

我有一个包含一些类(以及一些枚举和常量)的单元。任何人都会认识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.

现在显然是我的两个类TClickTClick 相当复杂。为了便于管理,我想将 TClickTClack 拆分为它们自己的单元同时不破坏任何现有的外部代码

我的第一个破解是:

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.pasCartalk_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.

问题当然是 TTappetBrotherTSolution 没有在这个单元中声明。因此,我们向 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴者 2024-10-05 05:13:46

编写一个单元:

unit Tappet;

interface

type
   TSolution = (solTransmission, solBrakes, solGremlins);

   TTappetBrother = class(TObject)
   public
      function GetSolution: TSolution; virtual; abstract;
   end;

implementation

end.

并在 ClickClack 单元中使用它。然后编写 CarTalk 单元以使用所有这三个并在其接口中导出所需的类型。不需要循环引用。

Write a unit:

unit Tappet;

interface

type
   TSolution = (solTransmission, solBrakes, solGremlins);

   TTappetBrother = class(TObject)
   public
      function GetSolution: TSolution; virtual; abstract;
   end;

implementation

end.

and use it in the Click and the Clack units. Then write the CarTalk unit to use all three and export the needed types in its interface. No circular references needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文