[fpc-devel] Overridden method with different signature - compiles - should it?

Sven Barth pascaldragon at googlemail.com
Sat Apr 5 13:27:06 CEST 2025


Martin Frb via fpc-devel <fpc-devel at lists.freepascal.org> schrieb am Sa.,
5. Apr. 2025, 12:02:

> See the below code. (tested 3.2.3 and 3.3.1)
>
> Is this intentionally allowed?
>
> Technically it should work. TSubTest.Test always returns something that
> fits the inherited requirement.
>
>
> program Project1;
> type
>    TFoo = class end;
>    TBar = class(TFoo) end;
>
>    TTest = class
>      function Test: TFoo; virtual; abstract;
>    end;
>
>    TSubTest = class(TTest)
>      function Test: TBar; override;
>    end;
>
> function TSubTest.Test: TBar;
> begin  end;
>
> begin  end.
>

Yes, this is intentional and is called "covariant return type" (
https://en.m.wikipedia.org/wiki/Covariant_return_type ).


>
> And if that is intentional, then why not also
>
>    TTest = class
>      procedure Test(a: TBar); virtual; abstract;
>    end;
>
>    TSubTest = class(TTest)
>      procedure Test(a: TFoo); override;
>    end;
>
> This fails. Even though any TBar passed will be fine to the base and the
> subclass.
>
> And any
>    var sub: TSubTest
> will accept TFoo too, but such a var can never hold the base class.
>

This is called contra-variance and is in general not something that
programming languages support. See for example here:
https://stackoverflow.com/questions/2995926/why-is-there-no-parameter-contra-variance-for-overriding

Regards,
Sven

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-devel/attachments/20250405/4c5e1281/attachment.htm>


More information about the fpc-devel mailing list