[fpc-devel] interfaces / inheritance / again -

Martin Frb lazarus at mfriebe.de
Mon Feb 2 21:22:50 CET 2026


On 02/02/2026 20:48, Michael Van Canneyt via fpc-devel wrote:
>
> Are you deliberately trying to shoot yourself in the foot here ?
> (better your foot than my foot obviously...)

Well, the simplest would be

    generic TGen<DATA>

no constraint, I can pass in whatever, and if it has the methods, then 
good ... (or well...)

But, that feels more like risking my foot. I quite prefer if I can give 
a constraint, and if the compiler will know earlier what the generic is 
about.

I have a list. Well several lists. They share some functionality.
But I can't just pack it into a base class.

For once, at least in some parts of the code, the list will only be 
known as "interface".

The lists have different item classes too.  So now I thought I write a 
generic that implements the shared bit.
Actually the shared bit is in another class, that accepts the list as 
argument. A worker class, if you will.

generic SharedBit<_BASE, _LIST, _ITEM> = class(_BASE)
   procedure ProcessItem(Itm: _ITEM);  virtual; // called by DoFoo
   procedure DoFoo(List: _LIST);
end;

procedure DoFoo(List: _LIST);
begin
   ProcessItem(List.Entries[i]);  // Entries must return the specific 
interface
end

ProcessItem must have the subclass, or at least the more specific interface.

And yes, I could add to the interface
   function GetObject: TObject
and then type cast that.
That feels like a bandaid.

Since I do have some code that has the list as interface, the simplest 
is that all code that does SharedBit uses the interfaces.
(Well, yes, leave away the constraint, and I can specialize for either 
class or interface)





>
> I assume this should be:
>
> property Bar: TBar read GetBar;
yes


>  property Bar: TSubBar read GetSubBar;
>
> property overrides exist, but they must keep the same type, they can only
> change the specifiers. So I don't think this will compile. If it does, it
> is probably by accident.

It does actually compile.

And on classes, properties can be reintroduces with any changes possible 
(wouldn't necessarily do but works)

On interfaces, it does not conflict with getting the interface by it 
GUID, or with what the interface "contains" => i.e. its definition, as 
it would be seen by any other code, e.g. a 3rd party lib.
The "property" doesn't change the VMT of the interface.

It really just defines an alias within the type name of the interface 
(almost like a type helper).

The inherited interface, now introduces a new method, with a new name, 
and a new type. Completely independent method. The parent VMT has 
nothing hidden, all fine so far.

The property just changes the alias, which function to call. And its not 
bound to the vmt, it hangs on the type name of the interface (at least 
my understanding).


>
> I don't know, but to me it looks like a definite way to confuse 
> yourself and others.
Not to much confusion. It returns the same entry, but with a different type.

Well, ok. its a different interface, but the object behind it is the 
same object. same instance. And the returned interface inherits from the 
original interface too (even though that isn't enforced by the compiler)

So functional it does the same thing. It just offers additional methods.

And those added methods are what I really need to access in the 
overridden "ProcessItem".


>
> I would define this as
>
>   ISubFoo = interface(Foo)
>     procedure GetSubBar: TSubBar;
>     property SubBar: TSubBar;
>   end;

Except, I must have it as
       property Bar: TSubBar;

=> because the code in the above generic will access "Bar".

I can pass the type for it (for the param in the virtual ProcessItem) to 
the generic.

But I can not pass the name of the property to the generic. The generic 
will always call "Bar"




More information about the fpc-devel mailing list