PDA

Ver la Versión Completa : Casting


annieruci
15-02-2011, 23:12:55
Me hace falta saber como puedo hacer un casting, tengo una clase persona, una clase estudiante y otra profesor, estas dos ultimas heredan de persona y ahora me hace falta meter los objetos en una lista de tipo persona y resulta que cuando intento acceder a los metodos de los hijos no me deja, como casteo para si es del tipo estudiante entre a un metodo y si es de tipo profesor entre a otro metodo

Saludos

droguerman
15-02-2011, 23:28:33
var
clase : TPersona;
begin
if (clase is TEstudiante) then
TEstudiante(clase).do_something
else
TDocente(clase).do_something_more;
end;

ecfisa
16-02-2011, 03:00:23
Hola.

Para algunos casos en particular, el uso del operador is puede dar resultados no esperados, ya que este devuelve verdadero
tanto si el objeto pertenece a la clase, como si es desciende de ella.

Por ejemplo:

var
Clase: TPersona;
begin
Clase:= TAlumno.Create;
if Clase is TPersona then
ShowMessage('TPersona')
else if Clase is TDocente then
ShowMessage('TDocente')
else
ShowMessage('TAlumno');
end;

Que muestra el mensaje 'TPersona' cuando el objeto creado es un TAlumno.

O también:

var
Clase: TPersona;
begin
Clase:= TAlumno.Create;
if Clase is TAlumno then
ShowMessage('TAlumno');
if Clase is TDocente then
ShowMessage('TDocente');
If Clase is TPersona then
ShowMessage('TPersona')
end;

Donde la salida es 'TAlumno' y 'TPersona'.

En casos que pueden prestarse a confusiones, una buena alternativa es usar la función ClassType que nos da dinámicamente
la referencia de clase del objeto:

var
Clase: TPersona;
begin
Clase:= TAlumno.Create;
if Clase.ClassType = TPersona then
ShowMessage('TPersona');
if Clase.ClassType = TDocente then
ShowMessage('TDocente');
if Clase.ClassType = TAlumno then
ShowMessage('TAlumno');
end;


Un saludo.

roman
16-02-2011, 15:22:35
resulta que cuando intento acceder a los metodos de los hijos no me deja, como casteo para si es del tipo estudiante entre a un metodo y si es de tipo profesor entre a otro metodo

Quizá, y sólo quizá, haya que replantear el problema. En teoría, si tu vas a procesar una lista de objetos, deberías restringirte únicamente a las operaciones permitidas para el objeto genérico sin preocuparte por la clase específica heredada.

Esto no quiere decir que no puedas efectuar operaciones de acuerdo a la clase específica. Pero de ello se encarga el polimorfismo. Si tu clase Persona tiene un método (virtual) HazEsto, las clases derivadas (Estudiante, Profesor, etc.) pueden redefinir dicho método para adaptarse a sus necesidades específicas.

Entonces, puedes recorrer la lista en forma genérica:


for I := 0 to ListaPersonas.Count -1 do
ListaPersonas[I].HazEsto;


con la seguridad de que, dependiendo del objeto, se llamará al método correcto.

// Saludos

annieruci
16-02-2011, 15:31:04
Gracias por la ayuda!!!!!!!!!

annieruci
16-02-2011, 15:57:55
for i:=0 to Length(lista)-1 do
begin
if lista[i].ClassType = TEstud then
edit4.text:= inttostr(lista[i].Getasignaturas);
end;

Me da error al llamar al metodo del hijo!!!!

annieruci
16-02-2011, 16:08:38
Ya se arreglo gracias a ustedes

Saludos

annieruci
16-02-2011, 16:11:00
for i:=0 to Length(lista)-1 do
begin
if lista[i].ClassType = TEstud then
edit4.text:= inttostr((lista[i] as TEstud).Getasignaturas);
end;

Lo que dice roman es muy util pero no para mi caso ya que no tiene sentido creo yo tener en una clase Estudiante un metodo getsueldo que solo este metodo es de los profesores.

Saludos

roman
16-02-2011, 16:16:05
creo yo tener en una clase Estudiante un metodo getsueldo que solo este metodo es de los profesores.


Y tienes razón. Pero tampoco tiene mucho sentido estar procesando una lista genérica si vas a terminar distinguiendo una u otra subclase ;) No es esta la filosofía OOP.

// Saludos