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.