I want to write a TCheckBox
and TRadioButton
descendants having 3 identical methods.
TMyCheckBox = class(TCheckBox)
procedure DoS
You are looking for implementation inheritance rather than interface inheritance. This is only achievable in Delphi if you can derive classes from a single common ancestor. This limitation is inherent because the language only 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 likewise for TMyRadioButton
etc.
Now, you could use interfaces and delegation to reduce some of the boilerplate, but there's no way for that to help with a message handler like WMSize
.