Delphi: How to add a different constructor to a descendant?

后端 未结 4 2072
深忆病人
深忆病人 2020-12-16 22:32

Update: The example i originally had was kind of complex. Here\'s a simple 8 line example that explains everything in one code block. The following

相关标签:
4条回答
  • 2020-12-16 23:18

    Also remember that constructors don't HAVE to be called Create. Older versions of Delphi didn't have method overloading, so you had to use different names:

    TComputer = class(TObject) 
    public 
        constructor Create(Cup: Integer); virtual; 
    end; 
    
    TCellPhone = class(TComputer) 
    private
      FTeapot: string;
    public 
        constructor CreateWithTeapot(Cup: Integer; Teapot: string); virtual; 
    end; 
    

    ...

    constructor TCellPhone.CreateWithTeapot(Cup: Integer; Teapot: string); 
    begin
      Create(Cup);
      FTeapot := Teapot;
    end;
    

    Both constructors will now be available.

    0 讨论(0)
  • 2020-12-16 23:28

    My immediate reaction is to use the overload keyword, as in:

    TCellPhone = class(TComputer)
    public
        constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
    end;
    

    Edit: Thanks Ian for the edit, which makes an answer out of my answer. I would like to think that I got it for bravery, so I am going to contribute a fuller example:

    program Project1;
    
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils;
    
    type
    
    TComputer = class(TObject)
    public
        constructor Create(Cup: Integer); virtual;
    end;
    
    TCellPhone = class(TComputer)
    public
        constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
    end;
    
    { TComputer }
    
    constructor TComputer.Create(Cup: Integer);
    begin
      writeln('constructed computer: cup = ', Cup);
    end;
    
    { TCellPhone }
    
    constructor TCellPhone.Create(Cup: Integer; Teapot: string);
    begin
      inherited Create(Cup);
      writeln('constructed cellphone: Teapot = ', Teapot);
    end;
    
    var
      C1, C2, C3: TComputer;
    
    begin
      C1 := TComputer.Create(1);
      Writeln;
      C2 := TCellPhone.Create(2);
      Writeln;
      C3 := TCellPhone.Create(3, 'kettle');
      Readln;
    end.
    

    with the result being:

    constructed computer: cup = 1
    
    constructed computer: cup = 2
    
    constructed computer: cup = 3
    constructed cellphone: Teapot = kettle
    
    0 讨论(0)
  • 2020-12-16 23:28

    You could create two new overloaded constructors, for example:

    type
      TXmlStream = class
      private
        FFileName: string;
      public
        constructor Create(const AFileName: string); virtual;
      end;
    
      TXhtmlStream = class(TXmlStream)
      private
        FEncoding: TEncoding;
      public
        constructor Create(const AFileName: string); overload; override;
        constructor Create(const AFileName: string; AEncoding: TEncoding); overload; virtual;
      end;
    
    constructor TXmlStream.Create(const AFileName: string);
    begin
      inherited Create;
      FFileName := AFileName;
    end;
    
    constructor TXhtmlStream.Create(const AFileName: string);
    begin
      inherited Create(AFileName);
    end;
    
    constructor TXhtmlStream.Create(const AFileName: string; AEncoding: TEncoding);
    begin
      inherited Create(AFileName);
      FEncoding := AEncoding;
    end;
    
    0 讨论(0)
  • 2020-12-16 23:31

    Another possibility is to write a new constructor with default parameter values where the part of the signature with non-default parameters matches the original constructor in the base class:

    type
      TXmlStream = class
      private
        FFileName: string;
      public
        constructor Create(const AFileName: string); virtual;
      end;
    
      TXhtmlStream = class(TXmlStream)
      private
        FEncoding: TEncoding;
      public
        constructor Create(const AFileName: string; AEncoding: TEncoding = encDefault); reintroduce; virtual;
      end;
    
    constructor TXmlStream.Create(const AFileName: string);
    begin
      inherited Create;
      FFileName := AFileName;
    end;
    
    constructor TXhtmlStream.Create(const AFileName: string; AEncoding: TEncoding);
    begin
      inherited Create(AFileName);
      FEncoding := AEncoding;
    end;
    
    0 讨论(0)
提交回复
热议问题