Reputation: 469
I'm reading the Nick Hodges' book "Coding in Delphi" to learn the Delphi Programming Language and I'm trying to understand the interface usage part in the book.
In a unit, I've put a simple interface:
unit INameInterface;
interface
type
IName = interface
['{CE5E1B61-6F44-472B-AE9E-54FF1CAE0D70}']
function FirstName: string;
function LastName: string;
end;
implementation
end.
and in another unit, I've put the implementation of this interface, according to the book sample:
unit INameImplementation;
interface
uses
INameInterface;
type
TPerson = class(TInterfacedObject, IName)
protected
function FirstName: string;
function LastName: string;
end;
implementation
{ TPerson }
function TPerson.FirstName: string;
begin
Result := 'Fred';
end;
function TPerson.LastName: string;
begin
Result := 'Flinstone';
end;
end.
At this point, I've created a simple VCL form application in order to use the object I've created. The form code is this:
unit main;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls, INameImplementation;
type
TfrmMain = class(TForm)
lblFirtName: TLabel;
lblLastName: TLabel;
txtFirstName: TStaticText;
txtLastName: TStaticText;
btnGetName: TButton;
procedure btnGetNameClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
Person: TPerson;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
begin
txtFirstName.Caption := '';
txtLastName.Caption := '';
end;
procedure TfrmMain.btnGetNameClick(Sender: TObject);
begin
txtFirstName.Caption := ...
end;
end.
My question is this: how can I use the interface? The two functions are declared as protected so how can I access them from the form? Do I have to define them as public, or should I use the INameInterface
interface unit?
I'm terribly confused about interfaces!!!
Upvotes: 8
Views: 949
Reputation: 612964
Essentially there are three things for you to know, beyond what you have already demonstrated understanding.
1. How to call methods of an interface
If you have a reference to an interface, then you can call methods just as you would on a class reference:
var
Name: IName;
....
Writeln(Name.FirstName);
Writeln(Name.LastName);
2. How to obtain interface references
Typically you do this by instantiating a class that implements the interface you wish to use:
var
Name: IName;
....
Name := TPerson.Create;
// now you can use Name as before
There are other ways to obtain interface references, but let's leave those to one side for now.
3. How to pass around interfaces
You might not wish to create a new object every time you need to use an interface. So you can get other parties to pass you the interface to use. For instance interfaces can be passed as method parameters:
procedure Foo(Name: IName);
begin
// use Name as before
end;
You can obtain interface references via function calls and properties, etc.
The two functions are declared as
protected
so how can I access them from the form?
Well, they are declared protected
in the implementing object. But you are not going to access them via the implementing object. You will access them via the interface. Which means that the visibility in the implementing object is not relevant from the perspective of the interface.
Your form unit references INameImplementation
which is needed to create the object that implements the interface. You'll also need to use INameInterface
so that your code can see the interface itself.
This example isn't very powerful yet because you can still see the implementing object's type. But imagine if that was hidden from you and all you could see was a function that returned an IName
. It's when you reach this point that interfaces can achieve their potential.
Upvotes: 9