¿Cómo puedo determinar si un objeto Delphi es de una clase específica y no de una clase descendiente?
class-design (5)
Tengo estas clases y un procedimiento:
TParent = class(TObject);
TChild1 = class(TParent);
TChild2 = class(TParent);
Procedure DoSomething(obj:TParent);
Lo que me gustaría hacer es cuando obj
es un TParent
y no un descendiente TParent
una excepción.
Pensé en hacer algo como esto:
if obj.classname = TParent.classname then raise exception.create....
pero parece un poco hackish (TM)
Más: Lo que pretendía es poder pasar objetos que compartían propiedades / procedimientos en común. Después de pensar más, el Objeto TParent no es realmente necesario en absoluto, lo que necesitaba era un objeto de interfaz que se muestra en mi respuesta.
Creo que he resuelto lo que estaba tratando de hacer, me golpeó en la cabeza anoche.
iParentInterface = interface(IUnknown);
TChild1 = class(TInterfacedObject,iParentInterface);
TChild2 = class(TInterfacedObject,iParentInterface);
Procedure DoSomething(obj:iParentInterface);
Está en el camino correcto, pero en lugar de comparar los ClassType
de clase, sería más sencillo verificar la propiedad ClassType
.
if obj.ClassType = TParent then raise exception.create....
Las buenas prácticas en la programación orientada a objetos establecen que esto no debe hacerse. Lo que estás describiendo es una violación directa del principio de sustitución de Liskov que establece que:
los objetos en un programa deben ser reemplazables con instancias de sus subtipos sin alterar la corrección de ese programa
Creo que deberías explicar qué problema estás tratando de resolver y entonces un mejor enfoque podría llegar a ser evidente.
Otro enfoque: introduzca un método abstracto en TParent, diga CheckValidChild , y anúlelo en las clases descendientes. Ahora, cuando llama a obj.CheckValidChild , obtiene un EAbstractError si la instancia de obj es de la clase TParent.
Probablemente encuentre útiles los siguientes métodos de clase TObject
:
- ClassType - devuelve la clase de un objeto
- ClassParent - da la clase padre de la clase
- InheritsFrom : devuelve si una clase se hereda de otra clase (es decir, comprueba toda la cadena de herencia). Incluye la clase actual.
Entonces, podrías lograr lo que quieres (desciende de TParent pero no TDescendant?) Con algo como el siguiente código (no probado, no tienes Delphi en este momento):
if obj.ClassType.InheritsFrom(TParent)
and not obj.ClassType.InheritsFrom(TDescendant) then...
O, si he entendido mal y usted solo quiere ver si un objeto es un TParent, y no es ningún tipo de descendiente, intente:
if obj.ClassType = TParent then...
Delphi se adelantó a su tiempo al proporcionar acceso a las clases a través de metaclasses , por lo que en lugar de solo verificar el nombre de la clase, puede acceder a un objeto de clase real.