Reading — step 1 of 5
Learn
Object Pascal interfaces are like Java/C# interfaces — abstract contracts that classes implement.
Defining
type
IDrawable = interface
['{B26E5476-1F73-4421-A8E1-9C42AB1C3D71}']
procedure Draw;
function Area: real;
end;
The GUID (['{...}']) uniquely identifies the interface — use Ctrl+Shift+G in Lazarus IDE to generate one. Required for COM/OLE compatibility; for plain in-process use it's optional but conventional.
Implementing
type
TCircle = class(TInterfacedObject, IDrawable)
private
FRadius: real;
public
constructor Create(R: real);
procedure Draw;
function Area: real;
end;
TInterfacedObject provides reference-counted memory management — much cleaner than manual Free. As long as you assign through interface variables, refcount handles cleanup.
Using
var d: IDrawable;
begin
d := TCircle.Create(5);
d.Draw;
WriteLn('area: ', d.Area);
{ No explicit Free — refcount drops to 0 when d goes out of scope }
end.
When the interface variable goes out of scope, refcount drops, the object is freed.
Multiple interfaces
A class can implement many:
TLogger = class(TInterfacedObject, ILogger, IDisposable)
...
end;
Interface inheritance
IBase = interface
procedure A;
end;
IDerived = interface(IBase)
procedure B;
end;
Classes implementing IDerived must implement A AND B.
Querying interfaces
var obj: TObject;
drawable: IDrawable;
begin
obj := TCircle.Create(5);
if Supports(obj, IDrawable, drawable) then
drawable.Draw
else
WriteLn('object does not draw');
end.
Supports is in SysUtils — checks and casts in one call. Returns false if not implemented.
Why interfaces matter
- Decouple modules: callers depend on
ILogger, not on a specific class - Enable mocking for tests
- Support multiple inheritance of behavior (Pascal classes can only single-inherit, but can implement many interfaces)
- Reference counting — easier memory management than raw classes
Caveats
- Mixing interface variables and class variables to the same object can confuse refcount — pick one
- Don't subclass
TInterfacedObjectin long chains — refcount setup is delicate - Performance: interface dispatch is slightly slower than direct class call (vtable indirection)
For large Pascal codebases, interfaces are how you keep modules from growing tightly coupled. Lazarus, FPC's RTL, and most CPAN-equivalent libraries are built around them.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…