我想写一个TCheckBox
和TRadioButton
后代,有3种相同的方法。
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;
我该怎么做?
答案 0 :(得分:11)
使用三种方法签名定义一个名为IDoSomething
的界面。
然后将您的班级声明更改为
TMyCheckBox = class(TCheckBox, IDoSomething)
然后实施。
如果实施很常见或非常接近。
然后定义一个帮助器类TDoSomething
,然后委派工作。
e.g。
Procedure TMyCheckBox.DoSomething1; // implements IDoSomething1
Begin
TDoSomething.DoSomething1(Self); // given class method will suffice.
End;
delphi中的类方法,相当于其他语言中的静态方法。
Type
TDoSomethingHelper = Class(TObject)
Public
Class Procedure DoSomething1(aComponent : TComponent);
End;
...
implementation
Class Procedure TDoSomethingHelper.DoSomething1(aComponent : TComponent);
Begin
aComponent.Tag = 27;
End;
答案 1 :(得分:8)
您正在寻找实现继承而不是接口继承。这只能在Delphi中实现,如果你可以从一个共同的祖先派生类。这种限制是固有的,因为该语言仅支持单继承。
你能做的最好的事情就是这样:
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;
同样适用于TMyRadioButton
等。
现在,您可以使用接口和委派来减少一些样板,但是没有办法帮助处理WMSize
之类的消息处理程序。