Need I to put overload or override words after the constructor declaration in derived class?

前端 未结 4 1009
不思量自难忘°
不思量自难忘° 2021-02-09 03:03

I have a class hierarchy, this one:

type
TMatrix = class
    protected
      //...
    public
      constructor Create(Rows, Cols: Byte);
    //...
type
  TMinMa         


        
相关标签:
4条回答
  • 2021-02-09 03:55

    You need overload for both constructors if they have the same name.

    type
      TMatrix = class
      protected
        //...
      public
        constructor Create(Rows, Cols: Byte);
        //...
    type
      TMinMatrix = class(TMatrix)
      public
        constructor Create(Rows, Cols: Byte); overload;
        constructor Create(var that: TMinMatrix); overload;
      end;
    

    It is good practice to call the inherited constructor.

    constructor TMinMatrix.Create(Rows, Cols: Byte);
    begin
       inherited Create(Rows, Cols); // Need to call the full name if the parameters are changed.
       //...
    end;
    
    0 讨论(0)
  • 2021-02-09 04:00

    Overload, tells the compiler that a method has the same name with different parameters.

    Override, tells the compiler that a method overrides it virtual or dynamic declared in the base class.

    Reintroduce, will hide the virtual or dynamic method declared in the base class.

    Theses definitions are from Ray Lischner's book {Delphi in a nutshell}

    type
      TFirst = class
      private
        FValue: string;
        FNumber: Integer;
      public
        constructor Create(AValue: string; ANumber: integer);
    
        property MyValue: string read FValue write FValue;
        property MyNumber: Integer read Fnumber write FNumber; 
      end;
    
      TSecond = class(TFirst)
      public
        constructor Create(AValue: string; ANumber: Integer);
      end;
    
    constructor TFirst.Create(AValue: string; ANumber: integer);
    begin
      MyValue := AValue;
      MyNumber := ANumber;
    end;
    
    { TSecond }
    
    constructor TSecond.Create(AValue: string; ANumber: Integer);
    begin
      inherited;
    end;
    

    The TSecond as it is declared will call the create of the TFirst, without the inherited, the TSecond members stay empty.

    0 讨论(0)
  • 2021-02-09 04:03

    As far as I know, there are two separate issues here:

    Making sure the child class' constructor calls the base class' constructor

    You'll have to explicitly call the base class' constructor:

    constructor TMinMatrix.Create(Rows, Cols: Byte);
    begin
       inherited;
       //...
    end;
    

    Making sure the child class' constructor overrides the base class' constructor

    You'll also have to make the child class' constructor override, and the base class' constructor virtual, to make sure the compiler sees the relation between the two. If you don't do that, the compiler will probably warn you that TMinMatrix's constructor is "hiding" TMatrix's constructor. So, the correct code would be:

    type
    TMatrix = class
        protected
          //...
        public
          constructor Create(Rows, Cols: Byte); virtual;    // <-- Added "virtual" here
          //...
    type
      TMinMatrix = class(TMatrix)
        private
          //...
        public
          constructor Create(Rows, Cols: Byte); override;   // <-- Added "override" here
          constructor CreateCopy(var that: TMinMatrix);
          destructor Destroy; override;                     // <-- Also make the destructor "override"!
      end;
    

    Note that you should also make your destructor override.

    Introducing a constructor with different parameters

    Note that you can only override a constructor with the same parameter list. If a child class needs a constructor with different parameters, and you want to prevent the base class' constructors from being called directly, you should write:

    type
    TMyMatrix = class(TMatrix)
    //...
    public
      constructor Create(Rows, Cols, InitialValue: Byte); reintroduce; virtual;
    //...
    end
    
    implementation
    
    constructor TMyMatrix.Create(Rows, Cols, InitialValue: Byte);
    begin
      inherited Create(Rows, Cols);   // <-- Explicitly give parameters here
      //...
    end;
    

    I hope this makes things more clear... Good luck!

    0 讨论(0)
  • 2021-02-09 04:04

    You need to call the inherited method explicitly; Delphi won't do it for you. This is by design, because there are cases where you're working with virtual methods, for example, when you do not want to invoke the inherited behavior.

    Also, as a matter of personal preference, I like to write out the inherited call completely. (inherited Create(Rows, Cols); as opposed to just inherited; for one simple reason: it makes it that much easier to traverse the code. If you've got a method call written out, you can control-click it and get to the ancestor method.

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