Implementacion de interfaces en VFP

(Difference between revisions)
Jump to: navigation, search
VictorEspina (Talk | contribs)
(Created page with "__FORCETOC__ Por ~~~ == Introducción == Las [http://en.wikipedia.org/wiki/Interface_(computing)#Software_interfaces interfaces] son una tecnica muy utilizada en OOP para e...")
Newer edit →

Revision as of 10:24, 10 April 2012


Por VictorEspina

Contents

Introducción

Las interfaces son una tecnica muy utilizada en OOP para extender la funcionalidad de una clase sin hacer uso de la herencia, asi como para determinar en tiempo de ejecución si un objeto dado puede interactuar con otro objeto desconocido, determinando si dicho objeto implementa una interfaz conocida.

En términos generales, una interfaz define una serie de propiedades y metodos que una clase debe implementar para cumplir con dicha interfaz. Esto permite a objetos distintos interactuar de forna segura entre ellos sin necesidad de conocer completamente sus interfaces sino SOLO si implementan una interfaz común.

Visual FoxPro no soporta la declaración y uso de interfaces de forma nativa. Este articulo muestra una forma de implementar de forma parcial las bodandes del uso de interfaces en VFP 6.0 o superior, mediante el uso de una clase helper.


Clase InterfaceHelper

La clase InterfaceHelper ofrece una forma de declarar interfaces de forma sencilla (aunque limitada, ya que no es posible indicar la firma de los metodos, es decir, la lista de parámetros que espera cada metodo y el valor devuelto) y determinar si un objeto dado implementa una interfaz previamente declarada.

Supongamos que tenemos la siguiente clase:

DEFINE CLASS Usuarios AS Custom
ENDDEFINE

En este punto, no tenemos forma de saber si una instancia de esa clase contiene "n" elementos ni como podemos recorrer dichos elementos. Es aqui donde entran las interfaces. Supongamos que declaramos una interfaz llamada IEnumerable que define las propiedades y metodos que debe implementar un objeto para poder recorrer su contenido:

PUBLIC goInterfaces
goInterfaces = CREATE("interfaceHelper")
goInterfaces.Declare("IEnumerable","count,items,@indexOf")

Lo que estamos diciendo aca es que existe una interfaz llamada IEnumerable que consiste de las propiedades Count y Items, asi como el metodo indexOf. Si ahora hacemos:

LOCAL oUsuarios
oUsuarios = CREATE("Usuarios")
?goInterfaces.Implements(oUsuarios, "IEnumerable") --> .F.

Podremos ver que la clase Usuarios no ofrece una forma de recorrer su contenido, ya que no implementa la interfaz IEnumerable. Ahora, solucionemos ese problema:

DEFINE CLASS Usuarios AS Custom
 Count = 0
 DIMEN Items[1]
 PROCEDURE indexOf(pcElement)
   ...
 ENDPROC
ENDDEFINE

Como se ve, esta nueva version de la clase Usuarios implementa las propiedades y metodos indicados en IEnumerable, por lo que ahora podemos hacer esto sabiendo de antemano que no obtendremos un error en tiempo de ejecución:

LOCAL oUsuarios
oUsuarios = CREATE("Usuarios")
IF goInterfaces.Implements(oUsuarios, "IEnumerable")
 FOR i = 1 TO oUsuarios.Count
  oUsuario = oUsuarios.Items[i] 
 ENDFOR
ENDIF


Las ventajas de esto pueden aplicarse a todo tipo de objetos. Supongamos que queremos determinar si un objeto dado puede recibir o no el foco:

goInterfaces.Declare("IFocusable","@setFocus")
 
IF goInterfaces.Implements(oObject, "IFocusable")
 oObject.setFocus()
ENDIF
<source>
 
 
 
== Codigo Fuente ==
<pre>
* INTERFACEHELPER.PRG
* Clase para soporte parcial de interaces en VFP 6.0 o superior
*
* Autor: Victor Espina
* Fecha: Abril 2012
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
* INTERFACEHELPER.PRG
* Clase para soporte parcial de interaces en VFP 6.0 o superior
*
* Autor: Victor Espina
* Fecha: Abril 2012
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
* Clase para soporte parcial de interaces en VFP 6.0 o superior
*
* Autor: Victor Espina
* Fecha: Abril 2012
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
*
* Autor: Victor Espina
* Fecha: Abril 2012
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
* Autor: Victor Espina
* Fecha: Abril 2012
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
* Fecha: Abril 2012
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
*
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 
 
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
*
DEFINE CLASS interfaceHelper AS Custom
 *
 DIMEN Interfaces[1]
 interfaceCount = 0
 
 * Constructor 
 PROCEDURE Init
  DIMEN THIS.Interfaces[1]
  THIS.interfaceCount = 0
 ENDPROC
 
 * Declare
 * Permite declarar una interfaz. Una interfaz se declara
 * indicando su nombre y su "firma", la cual consiste en una
 * lista de propiedades y metodos que deben implementar las
 * clases para ser compatibles con la interfaz.
 *
 * ej:
 * oInterfaces.Declare("IEnumerable","count,items,@indexOf")
 *
 * Los metodos se deben identificar con el prefijo @.
 *
 PROCEDURE Declare(pcName, pcSignature)
  LOCAL oInterface
  oInterface = CREATE("interfaceInfo")
  oInterface.Name = pcName
  oInterface.initWithSignature(pcSignature)
  THIS.interfaceCount = THIS.interfaceCount + 1
  DIMEN THIS.Interfaces[THIS.interfaceCount]
  THIS.Interfaces[THIS.interfaceCount] = oInterface
 ENDPROC
 
 
 * indexOf
 * Devuelve la posicion de una interfaz dada dentro de la coleccion
 * de interfaces o CERO si la interfaz no esta declarada.
 PROCEDURE indexOf(pcInterface)
  LOCAL i,nIndex
  nIndex = 0
  pcInterface = LOWER(pcInterface)
  FOR i = 1 TO THIS.interfaceCount
   IF LOWER(THIS.Interfaces[i].Name) == pcInterface
    nIndex = i
    EXIT
   ENDIF
  ENDFOR
  RETURN nIndex
 ENDPROC 
 
 
 * Accesor para la propiedad Interfaces. Esto permite
 * acceder a la coleccion de interfaces por posicion
 * o por nombre de la interfaz
 PROCEDURE Interfaces_Access(nIndex1, nIndex2)
  IF VARTYPE(nIndex1) = "N"
   RETURN THIS.Interfaces[nIndex1]
  ENDIF
  LOCAL nIndex
  nIndex = THIS.indexOf(nIndex1)
  IF nIndex > 0
   RETURN THIS.Interfaces[nIndex]
  ENDIF
 ENDPROC
 
 
 * Implements
 * Permite determinar si una instancia dada implementa
 * una interfaz especifica
 PROCEDURE Implements(poObjectRef, pcInterface)
  LOCAL nIndex,oInterface
  nIndex = THIS.IndexOf(pcInterface)
  IF nIndex = 0
   RETURN .F.
  ENDIF
 
  LOCAL lResult,i,cMember,cType,cMemberType,lIsMember
  oInterface = THIS.Interfaces[nIndex]
  lResult = .T.
  FOR i = 1 TO oInterface.memberCount
   cMember = oInterface.Members[i, 1]
   cType = oInterface.Members[i, 2]   
   IF THIS.getMemberType(poObjectRef, cMember) <> cType
    lResult = .F.
    EXIT
   ENDIF
  ENDFOR
 
  RETURN lResult
 ENDPROC
 
 
 * getMemberType
 * Funcion sustitua para PEMSTATUS() que funciona en todas
 * las versiones de VFP. Esto fue necesario debido a que
 * en VFP6 la llamada a PEMSTATUS() con el modo 3 genera un 
 * error sobre miembros tipo Property.
 HIDDEN PROCEDURE getMemberType(poObjectRef, pcMember)
  IF "09.00" $ VERSION()
   RETURN PEMSTATUS(poObjectRef, pcMember, 3)
  ENDIF
  DO CASE
     CASE NOT PEMSTATUS(poObjectRef, pcMember, 5)
          RETURN "None"
 
     CASE TYPE("poObjectRef." + pcMember) = "U"
          RETURN "Method"
 
     OTHERWISE
          RETURN "Property"
  ENDCASE
 ENDPROC
 *
ENDDEFINE
 

* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
* interfaceInfo (Class)
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
* Clase que representa los datos de una interfaz declarada
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro
*
DEFINE CLASS interfaceInfo AS Custom
 Signature = ""
 DIMEN Members[1,1]
 memberCount = 0
 
 * initWithSignature
 * Permite inicializar la interfaz con un string de firma que
 * contenga las propiedades y metodos que componen la interfaz
 PROCEDURE initWithSignature(pcSignature)
  LOCAL ARRAY laMembers[1]
  LOCAL nCount, i, cMember
  nCount = ALINES(laMembers, STRT(pcSignature,",",CHR(13)+CHR(10)))
  THIS.memberCount = nCount
  DIMEN THIS.Members[MAX(1, THIS.memberCount),2]
  FOR i = 1 TO nCount
   cMember = laMembers[i]
   IF LEFT(cMember,1) = "@"
    THIS.Members[i,1] = SUBS(cMember, 2)
    THIS.Members[i,2] = "Method"
   ELSE
    THIS.Members[i,1] = cMember
    THIS.Members[i,2] = "Property"
   ENDIF 
  ENDFOR
  THIS.Signature = pcSignature
 ENDPROC
 
ENDDEFINE
</pre>
 
[[Category:Visual FoxPro]]
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox