How to implement identical methods with 2 or more classes?

I want to write descendants of TCheckBox and TRadioButton , having 3 identical methods.

 TMyCheckBox = class(TCheckBox) procedure DoSomething1; procedure DoSomething2; procedure WMSize(var Message: TWMSize); message WM_SIZE; end; TMyRadioButton = class(TRadioButton) procedure DoSomething1; procedure DoSomething2; procedure WMSize(var Message: TWMSize); message WM_SIZE; end; // the following procedures are common for both classes, so in fact // TMyCheckBox.DoSomething1 do the same as TMyRadioButton.DoSomething1 procedure DoSomething1; begin // here is the same code for TMyCheckBox as well as for TMyRadioButton // but I don't want to write the same code many times but implement it // for both classes at once in some common way end; procedure DoSomething2; begin // here is the same code for TMyCheckBox as well as for TMyRadioButton // but I don't want to write the same code many times but implement it // for both classes at once in some common way end; procedure WMSize(var Message: TWMSize); message WM_SIZE; begin // here is the same code for TMyCheckBox as well as for TMyRadioButton // but I don't want to write the same code many times but implement it // for both classes at once in some common way end; 

How can i do this?

+6
source share
2 answers

Define an interface: IDoSomething with three method signatures.

Then change the class declaration to

 TMyCheckBox = class(TCheckBox, IDoSomething) 

and then do it.

If the implementations are general or very close.

Then define the helper class TDoSomething and then delegate the work.

eg.

 Procedure TMyCheckBox.DoSomething1; // implements IDoSomething1 Begin TDoSomething.DoSomething1(Self); // given class method will suffice. End; 

Class methods in delphi, equivalent to static methods in other languages.

 Type TDoSomethingHelper = Class(TObject) Public Class Procedure DoSomething1(aComponent : TComponent); End; ... implementation Class Procedure TDoSomethingHelper.DoSomething1(aComponent : TComponent); Begin aComponent.Tag = 27; End; 
+11
source

You are looking for inheritance of implementation, not inheritance of interfaces. This is only possible in Delphi if you can get classes from one common ancestor. This limitation is inherent because the language supports single inheritance.

The best you can do is something like this:

 type TMyWinControlExtender = class private FTarget: TWinControl; public constructor Create(Target: TWinControl); procedure WMSize(var Message: TWMSize; out CallInherited: Boolean); procedure DoSomething; end; TMyCheckBox = class(TCheckBox) private FExtender: TMyWinControlExtender; protected procedure WMSize(var Message: TWMSize); message WM_SIZE; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure DoSomething; end; TMyRadioButton = class(TRadioButton) private FExtender: TMyWinControlExtender; protected procedure WMSize(var Message: TWMSize); message WM_SIZE; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; procedure DoSomething; end; { TMyWinControlExtender } constructor TMyWinControlExtender.Create(Target: TWinControl); begin inherited Create; FTarget := Target; end; procedure TMyWinControlExtender.WMSize(var Message: TWMSize; out CallInherited: Boolean); begin if FTarget.... then .... CallInherited := ...; //etc. end; procedure TMyWinControlExtender.DoSomething; begin if FTarget.... then .... //etc. end; { TMyCheckBox } constructor TMyCheckBox.Create(AOwner: TComponent); begin inherited; FExtender := TMyWinControlExtender.Create(Self); end; destructor TMyCheckBox.Destroy; begin FExtender.Free; inherited; end; procedure TMyCheckBox.DoSomething; begin FExtender.DoSomething; end; procedure TMyCheckBox.WMSize(var Message: TWMSize); var CallInherited: Boolean; begin FExtender.WMSize(Message, CallInherited); if CallInherited then inherited; end; 

And also for TMyRadioButton , etc.

Now you can use interfaces and delegation to reduce part of the template, but there is no way to help this message handler, for example WMSize .

+8
source

Source: https://habr.com/ru/post/905623/


All Articles