The declaration of the TMessageClass
class does not need to know the specifics of how the TChatItemClass
class is declared, only that it is a class type, so use a forward declaration to break the circular unit dependancy of the two interface
sections, eg:
unit StackWeb.MessageClass;
interface
{uses
StackWeb.ChatItemClass;}
type
TChatItemClass = class; // <-- HERE
TMessageClass = class(TCardDefault)
private
FChat : TChatItemClass;
public
property chat : TChatItemClass read FChat write FChat;
end;
implementation
uses
StackWeb.ChatItemClass; // <-- MOVED HERE
...
end.
unit
StackWeb.ChatItemClass;
interface
uses
StackWeb.MessageClass;
type
TChatItemClass = class(TClassStandardList<TMessageClass>)
private
FMessages : TArray<TMessageClass>;
public
property messages : TArray<TMessageClass> read FMessages write FMessages;
end;
...
end.
This scenario is actually covered in Delphi's documentation:
Classes and Objects (Delphi): Forward Declarations and Mutually Dependent Classes
If the declaration of a class type ends with the word class
and a semicolon - that is, if it has the form
type className = class;
with no ancestor or class members listed after the word class
, then it is a forward declaration. A forward declaration must be resolved by a defining declaration of the same class within the same type declaration section. In other words, between a forward declaration and its defining declaration, nothing can occur except other type declarations.
Forward declarations allow mutually dependent classes. For example:
type
TFigure = class; // forward declaration
TDrawing = class
Figure: TFigure;
// ...
end;
TFigure = class // defining declaration
Drawing: TDrawing;
// ...
end;
Do not confuse forward declarations with complete declarations of types that derive from System.TObject without declaring any class members.
type
TFirstClass = class; // this is a forward declaration
TSecondClass = class // this is a complete class declaration
end;
TThirdClass = class(TObject); // this is a complete class declaration