[fpc-pascal] Interface delegates and the implements property specifier

Sven Barth pascaldragon at googlemail.com
Sun Dec 22 11:26:23 CET 2019


Am 22.12.2019 um 04:44 schrieb Ryan Joseph via fpc-pascal:
>
>> On Dec 21, 2019, at 10:49 AM, Adriaan van Os <fpc at microbizz.nl> wrote:
>>
>> I had hoped that procedure IMyInterface2.P2 would now be visible as a method of TMyClass. This would be quite helpful in implementing multiple-inheritance. But no, the implements specifier completely hides it. I assume this has been discussed before.
> That's exactly what I was ranting about some months back with the idea of "default properties". I would expect that syntax to pull the methods names into the current namespace and this would be very helpful.
>
> It's by design as Sven pointed out but this makes no sense whatsoever to me. If the compiler team agrees I will personally make a mode switch or whatever is permitted to accomplish this. :)
Vetoed.

You don't seem to understand what implementing an interface means in 
Object Pascal. It means that a class can be cast to an interface. It 
does *not* mean that the interface's methods are available from that class.

Take this:

=== code begin ===

program tintftest;

{$mode objfpc}
{$interfaces corba}

type
   ITest = interface
     procedure Test;
   end;

   TTest = class(TObject, ITest)
   strict private
     procedure Test;
   end;

procedure TTest.Test;
begin
end;

var
   t: TTest;
   i: ITest;
begin
   t := TTest.Create;
   //t.Test; // this does not compile
   i := t;
   i.Test;
end.

=== code end ===

An implementor can decide to have the interface's methods not accessible 
from outside.

Or take this:

=== code begin ===

program tintftest;

{$mode objfpc}
{$interfaces corba}

type
   ITest = interface
     procedure Test;
   end;

   TTest = class(TObject, ITest)
   public
     procedure ITest.Test = IntfTest;
     procedure IntfTest;
     procedure Test;
   end;

procedure TTest.Test;
begin
   Writeln('Test');
end;

procedure TTest.IntfTest;
begin
   Writeln('IntfTest');
end;

var
   t: TTest;
   i: ITest;
begin
   t := TTest.Create;
   t.Test;
   i := t;
   i.Test;
end.

=== code end ===

This will output

=== output begin ===

PS C:\fpc\git> .\testoutput\tintftest
Test
IntfTest

=== output end ===

So while TTest implements the ITest interface it's methods are not the 
same as the interface's.

Similar for delegates. The delegation property can be private (mostly 
protected though to avoid a "unused private symbol" warning), so you 
only get access to the delegated field by casting the class to the 
implemented interface.

Your proposal to hoist the methods of a delegated interface would 
conflict with this. Or it would require an alternative syntax to give 
the implementor the necessary control of the visibility.

TL;DR: in Object Pascal a class implementing an interface can be cast to 
that interface, but it does not need to present the methods of said 
interface.

Regards,
Sven


More information about the fpc-pascal mailing list