How to implement multiple inheritance in delphi?

前端 未结 9 736
一向
一向 2020-12-03 11:22

I\'m doing a full rewrite of an old library, and I\'m not sure how to handle this situation (for the sake of being understood, all hail the bike analogy):

I have the

相关标签:
9条回答
  • 2020-12-03 11:54

    You can try to extract an interface, say IFrontWheel, out of TBikeWheelFront, so that it is a subclass of TBikeWheel but implements IFrontWheel. Then TBikeWheelXYZ inherits from TBikeWheel and TBikeWheelFrontXYZ inherits from TBikeWheelXYZ and implements IFrontWheel.

    Then you can define a class TFrontwheel and give it the same methods as the interface, but now you implement them. Then TBikeWheelFront and TBikeWheelXYZ get a private member of type TFrontwheel and the IFrontWheel implementations of them simply delegate to the private member methods.

    This way you don't have double implementations.

    0 讨论(0)
  • 2020-12-03 11:54

    Another alternative with newer versions of Delphi is to leverage generics in a compositional model. This is particularly useful in the case where the multiple base classes (TBarA and TBarB in this example) are not accessible for modification (ie: framework or library classes). For example (note, the necessary destructor in TFoo<T> is omitted here for brevity) :

    program Project1;
    
    uses SysUtils;
    
    {$APPTYPE CONSOLE}
    
    type    
      TFooAncestor  = class
        procedure HiThere; virtual; abstract;
      end;
      TBarA = class(TFooAncestor)
        procedure HiThere; override;
      end;
      TBarB = class(TFooAncestor)
        procedure HiThere; override;
      end;
      TFoo<T: TFooAncestor, constructor> = class
        private
          FFooAncestor: T;
        public
          constructor Create;
          property SomeBar : T read FFooAncestor write FFooAncestor;
      end;
    
    procedure TBarA.HiThere;
    begin
      WriteLn('Hi from A');
    end;
    
    procedure TBarB.HiThere;
    begin
      WriteLn('Hi from B');
    end;
    
    constructor TFoo<T>.Create;
    begin
      inherited;
      FFooAncestor := T.Create;
    end;
    
    var
      FooA : TFoo<TBarA>;
      FooB : TFoo<TBarB>;
    begin
      FooA := TFoo<TBarA>.Create;
      FooB := TFoo<TBarB>.Create;
      FooA.SomeBar.HiThere;
      FooB.SomeBar.HiThere;
      ReadLn;
    end.
    
    0 讨论(0)
  • 2020-12-03 11:56

    Use interfaces. Something like this (Off the top of my head, based on your description.....)

    type
    
      IBikeWheel = interface
        ...
      end;
    
      IXYZ = interface
        ...
      end;
    
      IFrontWheel = interface(IBikeWheel)
        ...
      end;
    
    
      TBike = class
        ...
      end;
    
      TBikeWheel = class(TObject, IBikeWheel);
    
      TBikeWheelXYZ = class(TBikeWheel, IXYZ);
    
      TBikeFrontWheelXYZ = class(TBikeWheelXYZ, IFrontWheel);
    

    Then implement classes for the interfaces that do what the corresponding classes in your old (presumably C/C++) library does and instantiate them in the corresponding class's constructor.

    0 讨论(0)
提交回复
热议问题