poo polimorfismo modo hijo herencia ejemplos derivadas clases clase delphi inheritance constructor

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.