Casa
Top.Mail.Ru Yandeks.Metrika
Foro: "Principal";
Archivo actual: 2002.01.10;
Descargar: [xml.tar.bz2];

abajo

¿Cómo heredar el método no del padre, sino del padre del padre? Encontrar ramas similares


Knyaz17   (2001-12-21 11:47) [0]

Señor, por favor dime cómo puedes heredar el método no del padre, sino del padre del padre. Es decir, hay tres clases class1, Class2, Class3.
Se heredan en el orden de numeración; hay un método en Class3.
¿Cómo hacer que el método se ejecute en Class1, y luego inmediatamente en Class3 ???



Юрий Зотов   (2001-12-21 11:57) [1]

Especificar: ¿significa el método virtual (dinámico)?



Ю Ю   (2001-12-21 11:58) [2]

Por lo tanto, Class2 no es en absoluto el padre de Class3, ya que su método no satisface al heredero :-) Heredar directamente de Class1



McSimm   (2001-12-21 12:03) [3]

Si te refieres al método virtual (dinámico)
y si no me equivoco
entonces puedes

procedimiento TClass3.SomeMethod;
comenzar
// tu codigo
TClass1.SomeMethod
// tu codigo
final



Knyaz17   (2001-12-21 12:03) [4]

A Yu Yu:
Otros métodos, además, deben heredar de Class2.



Knyaz17   (2001-12-21 12:16) [5]

¿Y cómo declaro un método virtual (dinámico)?
Lo hago en las clases 1:
procedimiento ir; virtual;

y en Class2, Class3:
procedimiento ir; anular;

y no pasa nada si lo hago:
procedimiento TClass3.Go;
comenzar
TClass1.Go;
final
entonces el compilador jura.



Digitman   (2001-12-21 12:20) [6]

no es necesario hacer TClass1.Go virtual.

TClass1 = clase (...)
procedimiento ir;
fin;

TClass2 = clase (TClass1)
procedimiento ir;
fin;

TClass3 = clase (TClass2)
procedimiento ir;
fin;

procedimiento TClass3.Go;
comenzar
TClass1 (Self) .Go;
TClass2 (Self) .Go;
Vamos;
fin;




Knyaz17   (2001-12-21 12:22) [7]

¿O qué pasa si el método no es virtual?
Se puede hacer de alguna manera a través del diseño
¿heredado?

algo como
procedure TClass3.Go;
begin
inherited TClass1.Go;
end



Knyaz17   (2001-12-21 12:33) [8]

Para Digitman:

Tengo una estructura de módulos y en ellos no 3, pero se heredan muchas clases,
y organizado de la siguiente manera:

TClass1 = clase (...)
procedimiento ir; anular;
fin;

TClass2 = clase (TClass1)
procedimiento ir; anular;
fin;

TClass3 = clase (TClass2)
procedimiento ir; anular;
fin;

en consecuencia, no necesito llamar al método Go de la clase Class2, pero preferiblemente
solo en Class3.



Юрий Зотов   (2001-12-21 12:34) [9]

Doy un ejemplo de trabajo (ver el libro de Sergey Orlik "Secretos de Delphi sobre ejemplos"). En el proyecto: tres formas heredadas entre sí en una cadena. Cuando hace clic en el botón, se muestra un mensaje con el nombre del formulario. En la clase TForm3, el método virtual de "abuelo" se llama antes (así como así, inmediatamente "abuelo" - directamente, y no a través del "padre"). Lo que vemos en la pantalla.

El truco es que antes de llamar al método, se reemplaza la entrada a VMT (luego, por supuesto, debe restaurarse). Como resultado, la clase TForm3 parece convertirse temporalmente en la clase TForm1. Además, de esta manera, cualquier método de cualquier clase se puede llamar en general, independientemente de las relaciones de herencia.

unidad Unit1;

interfaz.

usos
Windows, Mensajes, Sistemas, Clases, Gráficos, Controles, Formularios, Diálogos,
StdCtrls, PInfoViewer, Grids, DBGrids;

tipo
TForm1 = clase (TForm)
Button1: TButton;
procedimiento Button1Click (Sender: TObject);
procedimiento FormShow (Sender: TObject);
público
procedimiento VirtualMethod; virtual;
fin;

var
Form1: TForm1;

implementación

usos
Unidad2, Unidad3;

{$ R * .DFM}

procedimiento TForm1.Button1Click (Sender: TObject);
comenzar
Método virtual
fin;

procedimiento TForm1.VirtualMethod;
comenzar
ShowMessage ("Form1")
fin;

procedimiento TForm1.FormShow (Sender: TObject);
comenzar
Form2.Show;
Form3.Show
fin;

fin.

=============================================== =======================

unidad Unit2;

interfaz.

usos
Windows, Mensajes, Sistemas, Clases, Gráficos, Controles, Formularios, Diálogos,
Unidad1, StdCtrls;

tipo
TForm2 = clase (TForm1)
público
procedimiento VirtualMethod; anular;
fin;

var
Form2: TForm2;

implementación

{$ R * .DFM}

procedimiento TForm2.VirtualMethod;
comenzar
ShowMessage ("Form2")
fin;

fin.

=============================================== =======================

unidad Unit3;

interfaz.

usos
Windows, Mensajes, Sistemas, Clases, Gráficos, Controles, Formularios, Diálogos,
Unidad2, StdCtrls;

tipo
TForm3 = clase (TForm2)
público
procedimiento VirtualMethod; anular;
fin;

var
Form3: TForm3;

implementación

{$ R * .DFM}

tipo
PClass = ^ TClass;

procedimiento TForm3.VirtualMethod;
var
OldClass: TClass;
comenzar
OldClass: = PClass (Self) ^;
PClass (Self) ^: = ClassParent.ClassParent;
tratar de
Método virtual
finalmente
PClass (Self) ^: = OldClass
fin;
ShowMessage ("Form3")
fin;

fin.




Алексей Петров   (2001-12-21 12:50) [10]

> Yuri Zotov.
Esto es puro hackeo basado en hecho indocumentadoque la instancia del objeto comienza con un puntero a VMT.
Teóricamente, en la próxima versión de Delphi esto puede dejar de funcionar. Aunque estoy casi seguro de que Borland dejará este hecho verdadero "para siempre" :)

Por cierto, la técnica también es adecuada para llamar dinámico método del abuelo sin cambios.



Alx2   (2001-12-21 12:53) [11]

Horror :)))
Puede, por supuesto, pero ¿vale la pena pervertir a través de RTTI?
Tal vez use objeto en lugar de clase. Allí puede llamar directamente al método de cualquiera de los antepasados. Aunque, por supuesto, se pierden otros encantos.
Pero, muy probablemente, tales problemas surgen debido a una jerarquía de clases construida incorrectamente.



McSimm   (2001-12-21 12:53) [12]

Pido disculpas por la respuesta no verificada.
Confundido con el diseñador.



Knyaz17   (2001-12-21 12:57) [13]

¡Sí, pero no funciona si el método class1 tiene el mismo método que se hereda en todas las clases!
Es decir, tengo:

TClass1 = clase (...)
procedimiento ir; anular;
procedimiento de actualización; anular;
fin;

TClass2 = clase (TClass1)
procedimiento ir; anular;
procedimiento de actualización; anular;
fin;

TClass3 = clase (TClass2)
procedimiento ir; anular;
procedimiento de actualización; anular;
fin;

y el método de actualización funciona en Go for Class1 !!!, pero en Class3 se anula y debería funcionar.



Knyaz17   (2001-12-21 13:01) [14]

Mi respuesta anterior fue una respuesta a un mensaje de Yuri Zotov.



Владислав   (2001-12-21 13:18) [15]

Traería el código real (parte de él).



Юрий Зотов   (2001-12-21 13:27) [16]

> Knyaz17 (21.12.01 13:01)

¿Y qué impide usar la misma técnica en TClass1.Go y eventualmente llamar a TClass3.Refresh desde allí? Además, el método Go se puede definir con el parámetro:

procedimiento Go (AClass: TClass = nil); virtual;

Luego, TClass3 lo llama como Go (OldClass), y TClass1 finalmente obtiene exactamente la clase cuyo método de actualización debe llamarse.



Knyaz17   (2001-12-21 13:32) [17]

¡Gracias a todos por participar en la discusión, y especialmente a Yuri Zotov!



Юрий Зотов   (2001-12-21 13:39) [18]

> Alexey Petrov © (21.12.01 12: 50)

> Esto es piratería pura, basada en un hecho indocumentado,
> que la instancia del objeto comienza con un puntero a VMT.

¿Por qué indocumentado? Aquí hay una cita de la ayuda de Delphi 5 (palabra clave de búsqueda VMT)

"Es un puntero al método virtual de la clase".

Entonces, todo es completamente legal. Y en futuras versiones no cambiará.



Knyaz17   (2001-12-21 13:43) [19]

¡Gracias a todos por participar en la discusión, y especialmente a Yuri Zotov!



Páginas: 1 rama entera

Foro: "Principal";
Archivo actual: 2002.01.10;
Descargar: [xml.tar.bz2];

arriba





Memoria: 0.62 MB
Tiempo: 0.032 c
1-28500
Hueso
2001-12-20 16:08
2002.01.10
Todavía hay una pregunta así surgió la transformación de Bitmap ov


1-28492
Delphimun
2001-12-21 14:24
2002.01.10
¿Cómo cambiar una letra unas letras hacia adelante (alfabéticamente)?


3-28405
Desdechado
2001-12-05 16:09
2002.01.10
Canal modem IB


6-28526
Perro Diamante
2001-10-14 17:21
2002.01.10
Deshabilitar la computadora a través de la red.


6-28513
atenuar
2001-10-15 02:19
2002.01.10
Código fuente http o cómo organizarlo ...





africaans albanés Arabic armenio Azerbaiyán vasco Bielorruso Bulgarian Catalán Chino (simplificado) Chino (tradicional) Croata Checo Danés Dutch Inglés Estonia filipina Finnish French
gallego georgiano Alemán Griego criollo haitiano Hebreo hindi Húngaro islandés Indonesian irlandés Italiano Japonés Korean letón lituano macedonio Malay maltés Noruego
persa polaco Portuguese Rumano Ruso Serbio Slovak Esloveno Español swahili Sueco Thai turco ucranio Urdu vietnamita galés yídish bengalí bosnio
cebuano esperanto gujarati hausa hmong igbo javanés kannada khmer lao latín maorí marathi mongol nepali punjabi somalí Tamil telugu yoruba
zulú
Английский Francés Alemán Italiano portugués Русский Español