0

My primary goal is to use SOLID principles while switching to Delphi language.

Let suppose I have a parent class Parent that I unfortunately can't edit or modify (e.g. part of the delphi library, hidden in private code..).

Parent = class;

And a child class, that I want to improve, by implementing an OOP interface ("interface" or "pure abstract class", used indistinctively from now on):

INiceInterface = interface
    procedure HelloWorld;
end;

Child = class(Parent, INiceInterface)
    procedure HelloWorld; override;
end;

When trying to do this, the compiler complains about:

E2291 Missing implementation of interface method INiceInterface._AddRef E2291 Missing implementation of interface method INiceInterface._Release E2291 Missing implementation of interface method INiceInterface.QueryInterface

Looking for those errors, I found the following text exploring solutions, with a quite negative conclusion: https://www.codeproject.com/Articles/1252175/Fixing-Delphis-Interface-Limitations

Considering that OOP is a quite mature concept, much older than Delphi, I am positively convinced that I am missing something, and that such a basic feature must be available in Delphi.


How to properly apply inverse dependency in Delphi? [ enfasis multiple interfaces ]

mjn
  • 36,362
  • 28
  • 176
  • 378
Adrian Maire
  • 14,354
  • 9
  • 45
  • 85
  • 2
    You don't need to modify Parent, Child can implement the missing reference counting code. You can "copy&paste" it from TInterfacedObject. – mjn May 30 '22 at 16:52
  • You don't necessarily need to use interfaces for the ``SOLID`` principals! – Delphi Coder May 30 '22 at 17:23
  • You should try to use composition rather than inheritance especially when you want to modify Delphi built-in classes. – Delphi Coder May 30 '22 at 17:33
  • @DelphiCoder Any suggestion how to apply inverse dependency without inheritance? – Adrian Maire May 30 '22 at 19:17
  • Just to be clear, I already read how to implement those _Add/Release, but that seems 1) an overkill for having inverse-dependency, and 2) seems to have quite some side-effects. – Adrian Maire May 30 '22 at 19:18
  • 1
    Yep, that is what we have in Delphi. There are no other "interface abstraction" features you could use. You just have to live with it. You must implement all those methods, however there are many ways to implement them and that can reduce some side-effects. But which path you will chose depends on your particular use case. Sometimes using their automatic memory management is a good thing to have, sometimes you want to disable it. – Dalija Prasnikar May 31 '22 at 11:25
  • Thank you @DalijaPrasnikar, I certainly want to disable any "memory management" that could interfere with my own code Create-FreeAndNil order. – Adrian Maire May 31 '22 at 11:35
  • My answer in linked question tells you how to do that. Just return -1 from _AddRef and _Release methods to do that. No other code in there is needed. – Dalija Prasnikar May 31 '22 at 11:39
  • @DalijaPrasnikar: reimplementing COM for each usage of an interface is a full No-Go. So I believe the answer to my question is: Delphi is not fully OOP and interfaces do not exists. – Adrian Maire May 31 '22 at 15:46
  • While interfaces in Delphi are far from perfect, your assessment that "they don't exist" is a bit of overreaction. You don't have to implement required methods in every class, you can implement them in base class of your class hierarchy or use already provided classes that have that basic implementation based on your needs. Because there is memory management aspect involved, you will usually want to have same rules for all classes in the hierarchy. Delphi interfaces can be successfully used as abstraction layer and for implementing multiple interfaces in a class. – Dalija Prasnikar Jun 01 '22 at 09:43
  • Yes, I know that this may be somewhat an issue if you deal with base classes outside of your reach, and implementing those methods is kind of a violation of a DRY principle, but it is not insurmountable problem. – Dalija Prasnikar Jun 01 '22 at 09:48

0 Answers0