FTP | CCD | Buscar | Trucos | Trabajo | Foros |
#1
|
|||
|
|||
Interfaces
Hola, no tengo muy claro todavia lo que son, ni para que sirven, me refiero a las INTERFACES. Asi que si alguien me puede ayudar, de la manera que sea, le estaria muy agradecido. Gracias
|
#2
|
||||
|
||||
Hay mucho texto sobre el tema, te recomiendo buscar el tema en cualquier libro, mismo en el "Delphi Developers Guide"... pero sencillamente las interfaces vienen a ser algo así como clases sin implementación, heredadas de IUnknown. Cuando creas una clase esta clase solo puede heredar de una clase, pero puede heredar de una clase y mas de una interface. Entonces con esto se logra algo similar a la herencia múltiple de otros lenguajes, sin tener el problema de seleccionar qué método implementar, en el caso de que una clase herede de dos clases con un método de igual nombre, como contrapartida tienes que implementar siempre todos los métodos de la interface, esto produce duplicación de código comparado contra la herencia múltiple.
Para los detalles, te recomiendo leer la ayuda que es muy clara en este aspecto. Saludos!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#3
|
||||
|
||||
dca:
Ya entrados en gastos, ¿conoces de algún ejemplo donde se vea que el uso de interfaces es realmente más conveniente que usar clases abstractas? Claro, omitiendo lo que mencionas de la simulación de herencia múltiple e interfaces COM. // Saludos |
#4
|
||||
|
||||
Si.. por ejemplo tengo un juego de componentes, del tipo Lookup que heredan de clases diferentes, pero todos estos tienen dos TDataLink´s cada uno, que llaman a métodos de estos componentes. Si no quiero usar interfaces ni RTTI, tengo que crear TDataLink´s específicos para cada clase de componente. Con las interfaces lo que hago es que cuando se crea cada DataLink el componente le asigne el componente dueño como interface, para que este pueda disparar los métodos sin importarle de que clase hallan heredado.
Espero haber sido claro, sino, no duden en consultarme! Saludos!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#5
|
||||
|
||||
¿Podrías aclarar un poco? Las interfaces ¿las usas para las clases o para los DataLink?
Ya sé que no puedes publicar el código pero un esqueleto no caería mal. // Saludos |
#6
|
||||
|
||||
Para las clases, los datalinks dispara métodos en las clases cuando estos reciben alguna notificación.
Esto es un pedazo muy recortado del código, así que no pretendan que funcione: La Interface: Código:
IDBLookupControl = interface ... procedure UpdateDataFields; procedure UpdateListFields; procedure ListLinkDataChanged; ... end; Código:
TListSourceLookupLink = class(TDataLink) private ILookup: IDBLookupControl; protected procedure ActiveChanged; override; procedure DataSetChanged; override; procedure LayoutChanged; override; ... public constructor Create(ALookupInterface: IDBLookupControl); ... end; implementation { TListSourceLookupLink } procedure TListSourceLookupLink.ActiveChanged; begin if Assigned(ILookup) then ILookup.UpdateListFields; end; constructor TListSourceLookupLink.Create(ALookupControl: TWinControl; ALookupInterface: IDBLookupControl); begin inherited Create; ... ILookup := ALookupInterface; end; procedure TListSourceLookupLink.DataSetChanged; begin if Assigned(ILookup) then ILookup.ListLinkDataChanged; end; procedure TListSourceLookupLink.LayoutChanged; begin if Assigned(ILookup) then ILookup.UpdateListFields; end; Código:
TCustomDBLookupControl = class(TCustomIncSearchEdit, IDBLookupControl) protected ... procedure UpdateDataFields; virtual; procedure UpdateListFields; virtual; procedure ListLinkDataChanged; virtual; abstract; ... end; ¿Fui claro?... sino, ya saben!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#7
|
||||
|
||||
Una Aclaración:
No pongo el resto de los componentes, porque el código es muy similar. Para que sirve esto, para que muchos componentes de clases diferentes reciban notificaciones desde los DataLinks, sin duplicar el código de estos. Algunos de estos componentes, los pueden bajar de mi página, pero sin el código fuente. Saludos!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#8
|
||||
|
||||
Ok. Pero ¿no puede hacerse así?
Código:
TDBLookupControl = class(TCustomIncSearchEdit) procedure UpdateDateFields; virtual; abstract; procedure UpdateListFields; virtual; abstract; procedure ListLinkDataChanged; virtual; abstract; end; Código:
TListSourceLookupLink = class(TDataLink) private Lookup: TDBLookupControl; protected procedure ActiveChanged; override; procedure DataSetChanged; override; procedure LayoutChanged; override; ... public constructor Create(ALookupInterface: IDBLookupControl); ... end; implementation { La misma, cambiando ILookup por Lookup } Código:
TCustomDBLookupControl = class(TDBLookupControl) protected ... procedure UpdateDataFields; override; procedure UpdateListFields; override; procedure ListLinkDataChanged; virtual; abstract; ... end; |
#9
|
||||
|
||||
No me serviría porque son componentes que vienen de clases diferentes de la VCL, o clases diferentes de componentes no orientado a datos, y no quiero agregarle métodos abstractos de datos.
¿Te convence?...
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#10
|
||||
|
||||
Cita:
// Saludos |
#11
|
||||
|
||||
Buen, en este caso es así, pero no me refería del todo a eso.
En este caso de TCustomIncSearchEdit, creo varios componentes.. si pruebas los que están en mi web (EditSuite), el TListSearchEdit y el TDBIncrementalSearch heredan de esta clase. En este caso el TListSearchEdit no tiene ninguna relación con bases de datos, así que no tiene porqué tener estos métodos. Si quiero puedo definirlos como protegidos, y sin implementación, pero no me parece muy prolijo. De todos modos el problema principal, es que puedo tener un componente heredado de TCustomEdit y otro TCustomComboBox con esta interface implementada, y la clase común de estos componentes es TWinControl. No voy a modificar TWinControl ni reescribir todo el código de estos componentes... ¿No? Espero tu respuesta!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#12
|
||||
|
||||
Permíteme poner otro ejemplo con controles más estandard para ver si estoy entendiendo.
Vamos a suponer que deseo procesar datos ya sea de un ListView o de un StringGrid por igual. Dado que desde un punto de vista lógico ambos no son otra cosa que una matriz podría definir: Código:
IMatriz = interface function Celdas(Ren, Col: Integer): String; end; Código:
TrmListView = class(TListView, IMatriz) function Celdas(Ren, Col: Integer): String; end; TrmStringGrid = class(TStringGrid, IMatriz) function Celdas(Ren, Col: Integer): String; end; De ser así, sí, sí me convences. // Saludos |
#13
|
||||
|
||||
En un ejemplo muy diferente... ¡¡Esa es la idea!!
Saludos!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#14
|
||||
|
||||
Cita:
La idea en ambos casos es dar a componentes disímiles una funcionalidad común ¿no? // Saludos |
#15
|
||||
|
||||
Cita:
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
|
|
|