Do not make methods protected unless you want them to be visible as public
Posted by jpluimers on 2020/11/18
One of the protection levels in Delphi is protected
. Originally meant for the class itself, that level is also visible to “friends”: anything in the same unit, for example:
unit BusinessLogicUnit; interface type TBusinessLogic = class(TObject) protected Procedure Foo(); // ... public // ... end; implementation // ... end.
You can even access them from outside that unit by using a trick like below.
Some people use the protected section so that unit tests can assess them using the below trick.
Do not do that!
It means anyone can use that trick, often doing more damage than good.
In this case, the trick was abused by a clever programmer that was relatively new to the code base. It resulted in unintended side effects.
unit HackUnit; interface implementation uses BusinessLogicUnit; type TBusinessLogicHack = class(TBusinessLogic); procedure Hack; var Instance: TBusinessLogicHack; begin Instance := TBusinessLogicHack.Create(); try Instance.Foo(); finally Instance.Free(); end; end; end.
Of course you can still access it like below.
It is slightly longer, but more importantly: much better shows the intent and how that intent is accomplished.
unit GoodUsageUnit; interface implementation uses BusinessLogicUnit; type TBusinessLogicDescendant = class(TBusinessLogic) public procedure Foo(); end; procedure TBusinessLogicDescendant.Foo(); begin inherited Foo(); // ... end; procedure Usage; var Instance: TBusinessLogicDescendant; begin Instance := TBusinessLogicDescendant.Create(); try Instance.Foo(); finally Instance.Free(); end; end; end.
–jeroen
dummzeuch said
Even private methods are accessible from other code within the same unit. To prevent that, you need to use “strict private”.