Interfaces de objetos en Delphi: interfaces de objetos

         

Tabla de contenido

1. Tipos de interfaz

Dos, interfaz y herencia (IInterfaz y herencia)

3. Identificación de interfaz y GUID (Identificación de interfaz y GUID)

4. Convenciones de llamada para interfaces

5. Propiedades de la interfaz

6. Declaraciones futuras


        Una interfaz de objeto, o interfaz para abreviar, define los métodos que una clase puede implementar. Las interfaces se declaran como clases, pero no se pueden crear instancias directamente y no tienen definiciones de métodos propias. En cambio, es responsabilidad de cualquier clase que admita una interfaz proporcionar implementaciones de los métodos de la interfaz. Una variable de un tipo de interfaz puede hacer referencia a un objeto de una clase que implementa la interfaz; sin embargo, sólo se pueden llamar los métodos declarados en la interfaz.

        Las interfaces tienen algunas de las ventajas de la herencia múltiple, pero sin las dificultades semánticas. Las interfaces también son esenciales para utilizar modelos de objetos distribuidos como SOAP. Al utilizar el modelo de objetos distribuidos, los objetos personalizados que admiten interfaces pueden interactuar con objetos escritos en C++, Java y otros lenguajes.

1. Tipos de interfaz

Las interfaces, al igual que las clases, sólo se pueden declarar dentro del alcance más externo de un programa o unidad, no dentro de procedimientos almacenados o declaraciones de funciones. Una declaración de tipo de interfaz tiene la siguiente forma:

type interfaceName = interface (ancestorInterface) ['{GUID}'] memberList end;

Advertencia: Para admitir la interoperabilidad COM de Win32, se requieren las especificaciones de interfaz ancestral y GUID . Asegúrese de especificar ancestroInterface y GUID si desea acceder a la interfaz a través de COM .

En la mayoría de los aspectos, una declaración de interfaz es similar a una declaración de clase, con las siguientes restricciones: 

  1. Las listas de miembros solo pueden incluir métodos y propiedades. No se permiten campos en las interfaces.
  2. Dado que las interfaces no tienen campos, las especificaciones de lectura y escritura de las propiedades deben ser métodos.
  3. Todos los miembros de una interfaz son públicos. No se permiten especificadores de visibilidad ni de almacenamiento. (pero las propiedades de la matriz se pueden declarar como predeterminadas).
  4. Las interfaces no tienen constructores ni destructores. No se pueden crear instancias de ellos excepto a través de clases que implementen sus métodos.
  5. Los métodos no se pueden declarar virtuales, dinámicos, abstractos o anulados ( virtual , dinámico , abstracto o anulado ). Dado que las interfaces no implementan sus propios métodos, estos nombres no significan nada.

A continuación se muestra un ejemplo de una declaración de interfaz: 

type IMalloc = interface(IInterface)
    ['{00000002-0000-0000-C000-000000000046}'] 
    function Alloc(Size: Integer): Pointer; stdcall; 
    function Realloc(P: Pointer; Size: Integer): Pointer; stdcall; 
    procedure Free(P: Pointer); stdcall;
    function GetSize(P: Pointer): Integer; stdcall;
    function DidAlloc(P: Pointer): Integer; stdcall;
    procedure HeapMinimize; stdcall;
  end;

En algunas declaraciones de interfaz, la palabra reservada de interfaz se reemplaza por dispinterface.

Dos, interfaz y herencia (IInterfaz y herencia)

        Las interfaces, al igual que las clases, heredan todos los métodos de sus antepasados. Pero las interfaces, a diferencia de las clases, no implementan métodos. Lo que hereda una interfaz es la obligación de implementar un método, que se pasa a cualquier clase que admita la interfaz.

        La declaración de una interfaz puede especificar una interfaz antecesora. Si no se especifica ninguna interfaz antecesora, es un descendiente directo de IInterface, que se define en la unidad del sistema y es el antecesor último de todas las demás interfaces. En Win32, IInterface declara tres métodos: QueryInterface, _AddRef y _Release.

Nota: IInterface es equivalente a IUnknown. En general, las aplicaciones independientes de la plataforma deberían usar IInterface, mientras que los programas específicos con dependencias de Win32 deberían permanecer en IUnknown.

        QueryInterface proporciona métodos para obtener referencias a las diferentes interfaces admitidas por un objeto. _AddRef y _Release proporcionan administración de memoria de por vida para las referencias de interfaz. La forma más sencilla de implementar estos métodos es derivar la clase de implementación del TInterfacedObject de la unidad del sistema. También puede implementar cualquiera de estos métodos como funciones vacías, pero el objeto COM debe administrarse mediante _AddRef y _Release.

Advertencia : Se requieren QueryInterface, _AddRef y _Release para admitir la interoperabilidad COM de Win32. Asegúrese de implementar estos métodos si desea acceder a la interfaz a través de COM.

3. Identificación de interfaz y GUID (Identificación de interfaz y GUID)

Una declaración de interfaz puede especificar un identificador único global (GUID), representado por una cadena literal entre paréntesis antes de la lista de miembros. La parte GUID de la declaración debe tener el siguiente formato:

 ['{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}']

        donde cada x es un dígito hexadecimal (0 a 9 o A a F). El editor de biblioteca de tipos genera automáticamente GUID para nuevas interfaces. También puede generar GUID presionando Ctrl+Shift+G en el editor de código.

        Un GUID es un valor binario de 16 bytes que identifica de forma única una interfaz. Si la interfaz tiene un GUID, se puede utilizar una búsqueda de interfaz para obtener una referencia a su implementación.

NOTA: Los GUID solo se utilizan para la interoperabilidad COM.

        Los tipos TGUID y PGUID declarados en la unidad del sistema se utilizan para manipular los GUID.

type 
     PGUID = ^TGUID;
     TGUID = packed record
       D1: Cardinal;
       D2: Word;
       D3: Word;
       D4: array[0..7] of Byte;
   end;

Se admiten dos métodos de llamada:

if Supports(Allocator, IMalloc) then ...

o

if Supports(Allocator, IID_IMalloc) then ...

Nota: La unidad SysUtils proporciona una función sobrecargada denominada Supports que devuelve verdadero o falso cuando los tipos de clases e instancias admiten una interfaz particular representada por un GUID. La función Soportes se utiliza de la misma forma que Delphi y como operadores. La diferencia es que el operando derecho de la función Supports puede ser un GUID o un tipo de interfaz asociado con un GUID, mientras que el operando derecho de los operandos is y as es un nombre de tipo. Consulte Referencias de clases para obtener más información sobre is y as.

4. Convenciones de llamada para interfaces

        La convención de llamada predeterminada para los métodos de interfaz es registrarse, pero las interfaces compartidas entre módulos (especialmente las interfaces escritas en diferentes idiomas) deben declarar todos los métodos usando stdcall. En Win32, puede utilizar Safecall para implementar el método de interfaz dual.

5. Propiedades de la interfaz

        Solo se puede acceder a las propiedades declaradas en una interfaz a través de expresiones de tipo de interfaz, no a través de variables de tipo de clase. Además, las propiedades de la interfaz sólo son visibles en programas que tienen la interfaz compilada.

        En las interfaces, las especificaciones de lectura y escritura de las propiedades deben ser métodos, ya que los campos no están disponibles.

6. Declaraciones futuras

        Una declaración de interfaz que termina con la palabra reservada interfaz y un punto y coma es una declaración directa si no se especifica ningún antepasado, GUID o lista de miembros. Una declaración directa debe resolverse mediante una declaración de definición de la misma interfaz en la misma sección de declaración de tipo. En otras palabras, entre la declaración directa y la declaración definitoria, no puede haber otras declaraciones que no sean declaraciones de otro tipo.

        Las declaraciones directas permiten interfaces interdependientes. Por ejemplo:

type 
   IControl = interface; 
   IWindow = interface 
       ['{00000115-0000-0000-C000-000000000044}'] 
       function GetControl(Index: Integer): IControl; 
         //. . . 
     end; 
   IControl = interface 
       ['{00000115-0000-0000-C000-000000000049}'] 
       function GetWindow: IWindow; 
       //. . . 
     end;

        No se permiten interfaces derivadas mutuamente. Por ejemplo, es ilegal derivar IWindow de IControl e IControl de IWindow.

Supongo que te gusta

Origin blog.csdn.net/sensor_WU/article/details/132492050
Recomendado
Clasificación