2012-01-10 22 views
6

Tôi muốn viết TCheckBoxTRadioButton con cháu có 3 phương pháp giống nhau.Làm cách nào để triển khai các phương thức giống hệt nhau với từ 2 Lớp trở lên?

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; 

Tôi làm cách nào để thực hiện việc này?

+0

Bạn có nghĩa là khai báo giống hệt nhau (sử dụng Giao diện) hoặc triển khai giống hệt nhau (sử dụng cùng tổ tiên)? – Kromster

+0

@Krom, Đó là một câu hỏi hay. Những gì tôi thực sự có nghĩa là thực hiện giống hệt nhau. – ZigiZ

+0

Bạn phải cho chúng tôi biết cách triển khai để có được câu trả lời hợp lệ. –

Trả lời

11

Xác định giao diện nói IDoSomething bằng ba chữ ký phương thức.

Sau đó thay đổi khai báo lớp của bạn để

TMyCheckBox = class(TCheckBox, IDoSomething) 

và sau đó thực hiện.

Nếu việc triển khai phổ biến hoặc rất gần.

Sau đó xác định lớp trợ giúp TDoSomething và sau đó ủy quyền tác phẩm.

ví dụ:

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

Phương thức lớp trong delphi, tương đương với phương pháp tĩnh bằng các ngôn ngữ khác.

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 Tôi sẽ thử. – ZigiZ

+0

Làm cách nào để xác định lớp trợ giúp như vậy trong D7? 'DoSomething1' có phải là phương thức lớp không? – ZigiZ

+0

Giữ tôi sẽ khuếch đại –

8

Bạn đang tìm kiếm thừa kế thực hiện thay vì kế thừa giao diện. Điều này chỉ có thể đạt được trong Delphi nếu bạn có thể lấy được các lớp từ một tổ tiên chung duy nhất. Giới hạn này là cố hữu vì ngôn ngữ chỉ hỗ trợ duy nhất thừa kế.

Điều tốt nhất bạn có thể làm là một cái gì đó như thế này:

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; 

Và tương tự như vậy cho TMyRadioButton, vv

Bây giờ, bạn có thể sử dụng giao diện và phái đoàn đến làm giảm một số các soạn sẵn, nhưng không có cách nào cho điều đó để trợ giúp với trình xử lý tin nhắn như WMSize.

+1

10x David. mã này trông thực sự tốt, đặc biệt là cách bạn xử lý WMSize. Nó có thể được thực hiện với các phương thức lớp đơn giản/hoặc TProcedure (chuyển 'Self' thành ref) nhiều hơn hoặc ít hơn những gì tôi đang làm hôm nay. những gì tôi đã hy vọng là "đa thừa kế" (sử dụng Giao diện), nhưng bây giờ tôi hiểu không có phép thuật ở đây. – ZigiZ

+1

Có thực sự. Không có nhiều kế thừa thực hiện trong Delphi.Rất ít ngôn ngữ hỗ trợ và trên thực tế nó thường gây ra nhiều rắc rối hơn nó đáng giá. –

Các vấn đề liên quan