polimorfismo las interfaz interfaces implementacion herencia ejemplos clase caracteristicas abstracta delphi interface delphi-2010

delphi - interfaces - Cuando una clase implementa una interfaz descendiente, ¿por qué no cuenta automáticamente como implementación de la interfaz base?



polimorfismo java (2)

Esto es así porque al principio OLE / COM tenía un error y Borland decidió ser compatible con él. Esto se menciona en este artículo: Nueva característica de lenguaje de Delphi: herencia múltiple para interfaces en Delphi para .NET . La solución es enumerar todas las interfaces de los ancestros explícitamente en la clase como escribió Mikael.

Algunas citas del artículo vinculado:

El problema estaba en la COM misma. Para cargar un módulo, COM cargaría la DLL, GetProcAddress en un punto de entrada conocido que debía exportarse desde la DLL, llamaría a la función DLL para obtener una interfaz IUnknown y luego QueryInterface para IClassFactory. El problema fue que cuando Microsoft agregó soporte para IClassFactory2, agregaron QueryInterface para IClassFactory2 después del código existente que buscaba IClassFactory. IClassFactory2 solo se solicitará si falla la consulta para IClassFactory.

Por lo tanto, COM nunca solicitaría IClassFactory2 en ningún servidor COM que implementara tanto IClassFactory2 como IClassFactory.

Este error existió en COM durante mucho tiempo. Microsoft dijo que no podían arreglar el cargador COM con un paquete de servicio del sistema operativo porque tanto Word como Excel (en ese momento) dependían del comportamiento defectuoso. Independientemente de si está arreglado en las últimas versiones de COM o no, Borland tiene que proporcionar alguna forma de preservar este comportamiento en Win32 Delphi en el futuro inmediato. De repente, agregar todos los ancestros a una clase de implementación que no existía antes es muy probable que rompa el código existente que accidentalmente cae en el mismo patrón que el cargador COM.

¿Cuál es la razón por la que esto no compila?

type IInterfaceA = interface [''{44F93616-0161-4912-9D63-3E8AA140CA0D}''] procedure DoA; end; IInterfaceB = interface(IInterfaceA) [''{80CB6D35-E12F-462A-AAA9-E7C0F6FE0982}''] procedure DoB; end; TImplementsAB = class(TSingletonImplementation, IInterfaceB) procedure DoA; procedure DoB; end; var ImplementsAB: TImplementsAB; InterfaceA: IInterfaceA; InterfaceB: IInterfaceB; begin ImplementsAB := TImplementsAB.Create; InterfaceA := ImplementsAB; >> incompatible types ... end

En contraste así es como lo hago funcionar:

InterfaceA := ImplementsAB as InterfaceB;

o

InterfaceA := InterfaceB;

Quiero decir, si IInterfaceB hereda de IInterfaceA y TImplementsAB implementa IInterfaceB, ¿no sería lógico implementar también IInterfaceA y ser compatible con el tipo?


Otra forma de hacerlo funcionar es incluir ambas interfaces en la declaración de clase.

TImplementsAB = class(TSingletonImplementation, IInterfaceA, IInterfaceB) procedure DoA; procedure DoB; end;

Supongo que esto es lo que se requiere para que el compilador se dé cuenta de que TImplementsAB implementa tanto IInterfaceA como IInterfaceB .