Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Herencia de interfaces, TAggregatedObject e implementación con "implements" keyword (https://www.clubdelphi.com/foros/showthread.php?t=77362)

LoPiTaL 18-01-2012 15:50:27

Herencia de interfaces, TAggregatedObject e implementación con "implements" keyword
 
Hola a todos!
Tengo una duda con la implementación de interfaces mediante la keyword "implements". Os comento: tengo las siguientes interfaces:

Código Delphi [-]
  IIntPadre = interface
    ['{14CB7AD1-9CC7-4805-A6FC-9DC8FC218F6A}']
    procedure dummie;
  end;

  IIntHija = interface (IIntPadre)
    ['{7D740013-C5E5-42C6-AFF0-9203A11BDDE9}']
    procedure dummie2;
  end;

Y tengo una clase que implementa sólo IIntPadre:

Código Delphi [-]
  TIntPadre=class (TAggregatedObject, IIntPadre)
  public
    procedure dummie;
  end;

Ahora quiero tener una clase que implemente las dos, y para ello hago lo siguiente:

Código Delphi [-]
  TIntHija=class (TInterfacedObject, IIntPadre, IIntHija)
  private
    FPadre: TIntPadre;
    function getPadre: IIntPadre;
  public
    property Padre: IIntPadre read getPadre implements IIntPadre;

    procedure dummie2;
  end;

De esta forma, los métodos de IIntPadre son comunes para todas las clases, ya que están implementados todos en TIntPadre. Sin embargo, al intentar implementar la interfaz con "implements", me da el siguiente error:

Cita:

[DCC Error] XXX.pas(12): E2291 Missing implementation of interface method IIntPadre.dummie
Si la interfaz IIntHija NO deriva de IIntPadre, no da ningún error y todo funciona perfecto.
Sin embargo, cuando hago que derive de IIntPadre, entonces me da este error.

¿Cómo puedo solucionarlo sin tener que declarar todos los métodos de IIntPadre e implementándolos a mano?

Un saludo,
LoPiTaL

Ñuño Martínez 19-01-2012 10:07:30

Cita:

Empezado por LoPiTaL (Mensaje 423231)
¿Cómo puedo solucionarlo sin tener que declarar todos los métodos de IIntPadre e implementándolos a mano?

De ninguna manera: Si tu clase usa la interface IIntPadre debe implementarla.

Otra cosa es que quieras que no las implemente porque esa clase no la vas a usar directamente sino que vas a extenderla de nuevo en otra clase que la herede. En ese puedes implementarla con métodos virtuales o abstractos.

LoPiTaL 19-01-2012 10:49:09

Cita:

Empezado por Ñuño Martínez (Mensaje 423297)
De ninguna manera: Si tu clase usa la interface IIntPadre debe implementarla.

Hombre, ya sé que debo implementar dicha interfaz :D
Tal vez me he expresado mal. Lo que pretendo hacer es que implemente IIntPadre mediante la keyword implements, de forma que ya no es necesario definir todos los métodos dentro de esta clase (ya que ya lo hace mediante una propiedad).

Sin embargo, el compilador no detecta que los métodos referentes a IIntPadre que se deben implementar debido a que IIntHija hereda de éste los puede implementar a través de la propiedad que implementa IIntPadre. Por eso, si hago que IIntHija no derive de IIntPadre, entonces compila perfectamente, pero si deriva de éste, entonces no me encuentra los métodos (que como digo, estarían en la propiedad que implementa a IIntPadre).

Un saludo,
LoPiTaL

Ñuño Martínez 22-01-2012 13:29:31

A ver, a ver, que creo que me he perdido.

Si IIntHija hereda de IIntPadre, entonces la clase que implemente IIntHija debe implementar también a IIntPadre. IIntHija no puede implementar ningún método de IIntPadre porque las interface no pueden implementar. Cuando creas una clase que implemente IIntPadre (TIntPadre), IIntHija sigue sin implementar ningún método. Ten en cuenta que estás creando un árbol en el que IIntPadre es el tronco y TIntPadre e IIntHija son dos ramas diferentes.

Por otro lado, al indicar en TIntHija tanto IIntPadre como IIntHija estás duplicando cosas: Con indicar IIntHija ya es suficiente, puesto que esta ya hereda a IIntPadre.

LoPiTaL 23-01-2012 08:46:25

Código Delphi [-]
Si IIntHija hereda de IIntPadre, entonces la clase que implemente IIntHija debe implementar también a IIntPadre

Correcto, entonces el código que he puesto en mi mensaje inicial debería compilar correctamente (lo recopio a continuación):

Código Delphi [-]
  IIntPadre = interface
    ['{14CB7AD1-9CC7-4805-A6FC-9DC8FC218F6A}']
    procedure dummie;
  end;

  IIntHija = interface (IIntPadre)
    ['{7D740013-C5E5-42C6-AFF0-9203A11BDDE9}']
    procedure dummie2;
  end;

  TIntPadre=class (TAggregatedObject, IIntPadre)
  public
    procedure dummie;
  end;

  TIntHija=class (TInterfacedObject, IIntPadre, IIntHija)
  private
    FPadre: TIntPadre;
    function getPadre: IIntPadre;
  public
    //Con esta propiedad pretendo implementar IIntPadre
    property Padre: IIntPadre read getPadre implements IIntPadre;

    //Este método para terminar la implementación de IIntHija
    procedure dummie2;
  end;

y sin embargo, no compila.

Cita:

Por otro lado, al indicar en TIntHija tanto IIntPadre como IIntHija estás duplicando cosas: Con indicar IIntHija ya es suficiente, puesto que esta ya hereda a IIntPadre.
Esto no es correcto, ya que si no defines explícitamente que TIntHija (o alguna de las clases de las que hereda) implementa IIntPadre, a pesar de que implemente IIntHija, cuando haces Support(miHija, IIntPadre, miPadre) te devuelve False (puede ser un bug de delphi, pero se comporta así).

Lo que estoy buscando, es alguna forma sencilla para que el código que he puesto compile.

Un saludo,
LoPiTaL

LoPiTaL 23-01-2012 16:31:43

A falta de encontrar una solución, he abierto dos QCs en Embarcadero, a ver qué opinan.

El de implements que iniciaba el hilo:
http://qc.embarcadero.com/wc/qcmain.aspx?d=102807

Y el de que hay que definir explícitamente todas las interfaces que implementa una clase:
http://qc.embarcadero.com/wc/qcmain.aspx?d=102808

cuando sepa algo más lo comento aquí.

Un saludo,
LoPiTaL


La franja horaria es GMT +2. Ahora son las 15:53:37.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi