I have a class hierarchy, this one:
type
TMatrix = class
protected
//...
public
constructor Create(Rows, Cols: Byte);
//...
type
TMinMatrix = class(TMatrix)
private
procedure Allocate;
procedure DeAllocate;
public
constructor Create(Rows, Cols: Byte);
constructor CreateCopy(var that: TMinMatrix);
destructor Destroy;
end;
So as you see, both derived and base class constructors have the same parameter list. I explicitly call base class constructor from derived one:
constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
inherited;
//...
end;
Is it necessary to explicitly call base class constructor in Delphi? May be I need to put overload or override to clear what I intend to do? I know how to do it in C++ - you need explicit call of a base class constructor only if you want to pass some parameters to it - but I haven`t much experience in Delphi programming.
Constructor looks like method but it is not. It does not have a return type and its name is same as the class name. But, a constructor cannot be overridden.
The derived class takes the responsibility of supplying the initial values to its base class. The constructor of the derived class receives the entire list of required values as its argument and passes them on to the base constructor in the order in which they are declared in the derived class.
Constructor Overriding is never possible in Java. This is because, Constructor looks like a method but name should be as class name and no return value. Overriding means what we have declared in Super class, that exactly we have to declare in Sub class it is called Overriding.
Because by using a super class's constructor we can access/initialize private members of a class. A constructor cannot be called as a method. It is called when object of the class is created so it does not make sense of creating child class object using parent class constructor notation. i.e. Child c = new Parent();
As far as I know, there are two separate issues here:
You'll have to explicitly call the base class' constructor:
constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
inherited;
//...
end;
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
.
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With