How to implement identical methods with 2 and more Classes?

后端 未结 2 1626
一生所求
一生所求 2021-01-18 11:58

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

TMyCheckBox = class(TCheckBox)
  procedure DoS         


        
2条回答
  •  伪装坚强ぢ
    2021-01-18 12:41

    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.

提交回复
热议问题