[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