2012-01-10 21 views
6

我想写一个TCheckBoxTRadioButton后代有3种相同的方法。如何使用2个或更多类实现相同的方法?

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

你的意思是相同的声明(使用接口)或相同的实现(使用相同的祖先)? – Kromster 2012-01-10 14:12:19

+0

@Krom,这是一个很好的问题。我的意思是相同的实现。 – ZigiZ 2012-01-10 16:44:12

+0

您必须向我们展示实施才能获得有效答案。 – 2012-01-10 16:50:26

回答

11

用三个方法签名定义一个接口说​​。

然后改变你的类声明

TMyCheckBox = class(TCheckBox, IDoSomething) 

,然后实现。

如果实现是常见或非常接近。

然后定义一个帮助类TDoSomething然后委派工作。

例如

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; 
+0

10x我会试试看。 – ZigiZ 2012-01-10 14:43:15

+0

如何在D7中定义这样的助手类? DoSomething1应该是一个类方法吗? – ZigiZ 2012-01-10 16:46:41

+0

等待我放大 – 2012-01-10 17:17:33

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; 

27:11 TMyRadioButton

现在,你可以使用接口和委派,以减少一些样板的,但没有办法为了帮助使用像WMSize这样的消息处理程序。

+1

10x David。这段代码看起来非常好,特别是你如何处理WMSize。它可以通过简单的类方法/或TProcedure(通过'Self'作为参考)来完成,或多或少是我今天所做的。我所希望的是“多继承”(使用接口),但现在我明白这里没有魔法。 – ZigiZ 2012-01-10 21:19:31

+1

是的。在Delphi中没有多重继承的实现。很少有语言支持这一点,事实上它经常会导致比它的价值更大的麻烦。 – 2012-01-10 21:21:11

相关问题