2012-02-14 10 views
6

sólo quería hacer una simple pregunta - tengo una clase derivada de TLabel de la siguiente manera:sustituida y se constructora no anulado

TMyLabel = class (TLabel) 
    ... 
    constructor Create(AOwner: TComponent); override; 
end; 

constructor TMyLabel.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    { some code } 
end; 

Ahora, Delphi me permite compilar las dos versiones con y sin el anulación . ¿Podrías explicar cuáles son las diferencias? Aparte de no poder solicitar mis propios parámetros en Create() cuando se reemplazó. Gracias

Edit: Lo que quiero decir es - ¿cuál es la diferencia entre un virtual y un non-virtual constructor descendiente? Siempre puedo llamar al constructor heredado por inherited Create(), entonces, ¿cuál es el punto?

+0

posible duplicado de [¿Necesito sobrecargar o reemplazar las palabras después de la declaración del constructor en la clase derivada?] (Http://stackoverflow.com/questions/360597/need-i-to-put-overload-or-override -words-after-the-constructor-declaration-in-de) –

+0

El compilador le da una advertencia si no lo hace, ¿verdad? del duplicado vinculado; "Si no haces eso, el compilador probablemente te advierta que el constructor de TMinMatrix está" ocultando "el constructor de TMatrix. - Todavía tengo que encontrar una NECESIDAD práctica para ocultar un constructor de componentes, y TCOmponent en particular parece depender de un comportamiento virtual adecuado para Constructores y Destructores, por lo que, en general, con TComponent, en realidad está cerca de un error. –

+0

Sí, lo hace. Podría estar 'escondiéndolo' en el sentido de que no es _directamente_ descendiente, pero como lo llamo 'heredado' de todos modos, ¿hace alguna diferencia? –

Respuesta

9

Los constructores virtuales permiten la creación de instancias polimórficas de objetos. El ejemplo clásico de esto es el mecanismo de transmisión de .dfm de Delphi.

El código que lee archivos .dfm y formularios de instancias no sabe en tiempo de compilación qué clases usar. La decisión se pospone hasta el tiempo de ejecución cuando se puede realizar correctamente, es decir, cuando se lee el archivo .dfm. Además, puede obtener el mecanismo de archivo .dfm para crear componentes personalizados que no formen parte de la VCL, por lo que este mecanismo .dfm debe ser capaz de instanciar correctamente las clases que no forman parte de la VCL.

El constructor de TComponent se declara así:

constructor Create(AOwner: TComponent); virtual; 

Para un componente para participar en este mecanismo se debe declarar su constructor con la directiva override.

La otra clave del proceso son las referencias de clase. Por ejemplo

type 
    TComponentClass = class of TComponent; 

El código que crea componentes al leer archivos .dfm, más o menos, se parece a esto:

var 
    ComponentClass: TComponentClass; 
    Component, Owner: TComponent; 
.... 
ComponentClass = FindComponentClass(ReadComponentClassName); 
Component := ComponentClass.Create(Owner); 

Ahora, si el mecanismo no hizo uso de constructores virtuales a continuación, el constructor que se llamaría sería TComponent.Create. Y entonces su constructor, TMyLabel.Create nunca sería llamado.

Es por eso que debe incluir la directiva de anulación en sus constructores cuando se deriva de TComponent.

+0

Gracias. Sin embargo, en caso de que quisiera permitir otras derivaciones de 'TMyLabel' Y quería especificar más parámetros en el momento de la creación, ¿sería posible? –

+0

@MartinMelka No, eso simplemente no es posible si va a tener el mecanismo .dfm instanciar su etiqueta. Siempre va a llamar al constructor virtual con el único parámetro. Probablemente deberías estar de acuerdo con ese constructor y agregar un método o propiedades para permitir que tus parámetros adicionales sean suministrados después de la creación. –

+0

Eso pensé, gracias por aclarar eso –

2

Bueno, si recuerdo correctamente Delphi (eso fue hace un tiempo, aunque fue un buen momento :)) cuando se invalida el constructor podrás llamarlo por referencias de clase (ver this spec como ejemplo).

+0

Los constructores virtuales correctos y anulados pueden ser invocados por fábricas de clase que solo conocen la clase base donde se declaró el constructor por primera vez. –

Cuestiones relacionadas