delphi - polimorfismo - ¿Necesito sobrecargar o reemplazar palabras después de la declaración del constructor en la clase derivada?
la herencia es un modo de (4)
Hasta donde yo sé, hay dos cuestiones separadas aquí:
Asegurándose de que el constructor de la clase secundaria llama al constructor de la clase base
Tendrás que llamar explícitamente al constructor de la clase base:
constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
inherited;
//...
end;
Asegurándose de que el constructor de la clase secundaria anule el constructor de la clase base
También tendrá que hacer que el constructor de clase secundaria y el constructor de clase base sean virtual
para asegurarse de que el compilador ve la relación entre los dos. Si no haces eso, es probable que el compilador te advierta que el constructor de TMinMatrix está "ocultando" el constructor de TMatrix. Entonces, el código correcto sería:
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;
Tenga en cuenta que también debe hacer que su destructor se override
.
Presentamos un constructor con diferentes parámetros
Tenga en cuenta que solo puede anular un constructor con la misma lista de parámetros. Si una clase secundaria necesita un constructor con parámetros diferentes, y usted quiere evitar que los constructores de la clase base sean llamados directamente, debe escribir:
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;
Espero que esto aclare las cosas ... ¡Buena suerte!
Tengo una jerarquía de clase, esta:
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;
Como puede ver, tanto los constructores de clase base como los derivados tienen la misma lista de parámetros. Llamo explícitamente al constructor de la clase base del derivado:
constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
inherited;
//...
end;
¿Es necesario llamar explícitamente al constructor de la clase base en Delphi? ¿Puede ser que necesite sobrecargar o anular para aclarar lo que pretendo hacer? Sé cómo hacerlo en C ++, necesitas una llamada explícita de un constructor de clase base solo si quieres pasarle algunos parámetros, pero no tengo mucha experiencia en la programación de Delphi.
Necesita sobrecarga para ambos constructores si tienen el mismo nombre.
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;
Es una buena práctica llamar al constructor heredado.
constructor TMinMatrix.Create(Rows, Cols: Byte);
begin
inherited Create(Rows, Cols); // Need to call the full name if the parameters are changed.
//...
end;
Sobrecarga, le dice al compilador que un método tiene el mismo nombre con diferentes parámetros.
Override, le dice al compilador que un método lo anula virtual o dinámico declarado en la clase base.
Reintroduce, ocultará el método virtual o dinámico declarado en la clase base.
Estas definiciones provienen del libro de Ray Lischner {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;
El TSecond como está declarado llamará a la creación del TFirst, sin el heredado, los miembros TSecond permanecen vacíos.
Debe llamar al método heredado explícitamente; Delphi no lo hará por ti. Esto es por diseño, porque hay casos en los que está trabajando con métodos virtuales, por ejemplo, cuando no desea invocar el comportamiento heredado.
Además, como una cuestión de preferencia personal, me gusta escribir la llamada heredada por completo. ( Heredado Create (Filas, Cols); en lugar de simplemente heredado, por una simple razón: hace que sea mucho más fácil atravesar el código. Si tiene una llamada de método escrita, puede hacer clic y hacer clic en ella para obtener al método ancestro.