Sección de tutoriales y manuales vb

Tutorial sobre los módulos de clase

4 - Polimorfismo

Volver al índice



 

 

Tutorial realizado por JOEL ALEJANDRO

4 - Polimorfismo - Contenido

  1. Introducción
  2. Cómo proporciona Visual Basic el polimorfismo
  3. Creación e implementación de una interfaz
  4. Implementación de propiedades
  5. Tiempo muerto para una breve descripción de objetos e interfaces
  6. Múltiples facetas (e interfaces) de la reutilización del código

 

 


1 - Introducción

 

Polimorfismo significa que muchas clases pueden proporcionar la misma propiedad o el mismo método y que el que llama no tiene por qué saber la clase a la que pertenece el objeto antes de llamar a la propiedad o al método.

Por ejemplo, una clase Pulga y una clase Tiranosaurio podrían tener las dos un método Morder. El polimorfismo significa que puede invocar Morder sin saber si el objeto es una Pulga o un Tiranosaurio, aunque seguramente lo descubrirá después.

Los siguientes temas describen la implementación del polimorfismo en Visual Basic y cómo puede utilizarlo en sus programas.

 

Para obtener más información En la Edición profesional y en la Edición empresarial de Visual Basic el polimorfismo se convierte en un poderoso mecanismo para la evolución de los sistemas de componentes software. Esto se describe en “Principios generales del diseño de componentes”, en la sección Crear componentes ActiveX de la Guía de herramientas componentes.

 


2 - Cómo proporciona Visual Basic el polimorfismo

 

La mayoría de los sistemas de programación orientada a objetos proporcionan polimorfismo mediante la herencia. Es decir, las hipotéticas clases Pulga y Tiranosaurio pueden heredar características de una clase Animal. Cada clase invalidaría el método Morder de la clase Animal para aportar sus propias características de mordedura.

El polimorfismo proviene del hecho de que puede llamar al método Morder de un objeto que pertenezca a cualquier clase derivada de Animal sin conocer la clase a la que pertenece el objeto.

Proporcionar polimorfismo mediante interfaces

Visual Basic no utiliza la herencia para proporcionar polimorfismo. Visual Basic proporciona el polimorfismo mediante múltiples interfaces ActiveX. En el Modelo de objetos componentes (COM) que forma la infraestructura de la especificación ActiveX, las múltiples interfaces permiten que los sistemas de componentes software evolucionen sin afectar al código existente.

Una interfaz es un conjunto de propiedades y métodos relacionados. Gran parte de la especificación ActiveX se ocupa de la implementación de interfaces estándar para obtener servicios del sistema o para proporcionar funcionalidad a otros programas.
En Visual Basic podría crear una interfaz Animal e implementarla en las clases Pulga y Tiranosaurio. Después podría invocar el método Morder de cualquiera de los dos tipos de objeto sin conocer su tipo.

Polimorfismo y rendimiento

El polimorfismo es importante por razones de rendimiento. Para comprobarlo, observe la función siguiente

Public Sub Alimentarse(ByVal Critter As Object, _
ByVal Food As Object)
	Dim dblDistance As Double
	' Código para calcular la distancia a la comida 
	'(omitido).
	Critter.Mover dblDistance	' Enlace en tiempo de 
										' compilación
	Critter.Morder Food			' Enlace en tiempo de 
										' compilación
End Sub
 

 

Los métodos Mover y Morder son enlaces en tiempo de compilación con Critter. El enlace en tiempo de compilación tiene lugar cuando Visual Basic no puede determinar en tiempo de compilación el tipo de objeto que contendrá una variable. En este ejemplo, el argumento Critter está declarado como As Object, de forma que en tiempo de ejecución pueda contener una referencia a cualquier tipo de objeto, como un Coche o una Roca.

Como no puede saber cuál será el objeto, Visual Basic compila una parte de código adicional para preguntar al objeto si acepta el método llamado. Si el objeto acepta el método, dicho código adicional lo invoca; si no, el código adicional desencadena un error. Todas las llamadas a métodos o a propiedades incurren en esta carga adicional.

Por el contrario, las interfaces permiten los enlaces en tiempo de diseño. Cuando Visual Basic conoce en tiempo de compilación la interfaz que se va a llamar, puede comprobar en la biblioteca de tipos si dicha interfaz acepta el método. Después, Visual Basic puede compilar un salto directo al método, mediante una tabla virtual de funciones (vtable). Esto es muchas veces más rápido que el enlace en tiempo de compilación.

Ahora suponga que los métodos Mover y Morder pertenecen a la interfaz Animal y que todas las clases de animales implementan esta interfaz. Ahora podría declarar el argumento Critter como As Animal y los métodos Mover y Morder se enlazarán en tiempo de diseño:

Public Sub Alimentarse(ByVal Critter As Animal, _
ByVal Food As Object)
	Dim dblDistance As Double
	' Código para calcular la distancia a la comida 
	'(omitido).
	Critter.Mover dblDistance	' Enlace en tiempo de 
										' diseño.
	Critter.Morder Food			' Enlace en tiempo de 
										' diseño.
End Sub
 

 


3 - Creación e implementación de una interfaz

 

Como se ha explicado en “Cómo proporciona Visual Basic el polimorfismo”, una interfaz es un conjunto de propiedades y métodos. En el siguiente ejemplo de código creará una interfaz Animal y la implementará en dos clases, Pulga y Tiranosaurio.

Puede crear la interfaz Animal si agrega un módulo de clase al proyecto, le asigna el nombre Animal e inserta el código siguiente:

Public Sub Mover(ByVal Distance As Double)


End Sub


Public Sub Morder (ByVal What As Object)


End Sub 

 

Observe que estos métodos no contienen código. Animal es una clase abstracta, que no contiene código de implementación. El propósito de una clase abstracta no es crear objetos, sino proporcionar una plantilla de interfaz que puede agregar a otras clases. (Aunque, como verá, algunas veces resulta útil implementar la interfaz de una clase no abstracta; esto se describe más adelante en este tema.)

Nota Hablando con propiedad, una clase abstracta es una clase a partir de la cual no puede crear objetos. Siempre puede crear objetos a partir de clases de Visual Basic, incluso aunque no contengan código; así, no son realmente abstractas.

Ahora puede agregar dos módulos de clase más. Asigne a uno de ellos el nombre Pulga y al otro Tiranosaurio. Para implementar la interfaz Animal en la clase Pulga, utilice la instrucción Implements:

Option Explicit
Implements Animal

 

En cuanto agregue esta línea de código, puede hacer clic en la lista desplegable (Objeto) de la izquierda de la ventana Código. Una de las entradas será Animal. Cuando la seleccione, la lista desplegable (Procedimiento) de la derecha mostrará los métodos de la interfaz Animal.

Seleccione los métodos de uno en uno para crear plantillas de procedimiento vacías en todos los métodos. Las plantillas tendrán los argumentos y los tipos de datos correctos, como se han definido en la clase Animal. Cada nombre de procedimiento tendrá el prefijo Animal_ para identificar la interfaz.

Importante Una interfaz es como un contrato. Al implementar la interfaz, una clase se compromete a responder cuando se invoque cualquier propiedad o método de la interfaz. Por tanto, debe implementar todas las propiedades y los métodos de una interfaz.

Ahora puede agregar el código siguiente a la clase Pulga:

Private Sub Animal_Mover(ByVal Distance As Double)
	' (Se omite el código del salto.)
	Debug.Print "Pulga movida"
End Sub

Private Sub Animal_Morder(ByVal What As Object)
	' (Se omite el código del picotazo.)
	Debug.Print "La pulga mordió un " & TypeName(What)
End Sub 

 

Puede que se pregunte por qué los procedimientos se declaran Private. Si fueran Public, los procedimientos Animal_Mover y Animal_Morder formarían parte de la interfaz Pulga y tendría el mismo enlace original, al declarar el argumento Critter As Object para que pueda contener una Pulga o un Tiranosaurio.

Múltiples interfaces

La clase Pulga tiene ahora dos interfaces: la interfaz Animal recién implementada, que tiene dos miembros, y la interfaz Pulga predeterminada, que no tiene miembros. Más adelante en este ejemplo agregará un miembro a una de las interfaces predeterminadas.

Puede implementar la interfaz Animal de forma similar para la clase Tiranosaurio:

Option Explicit
Implements Animal

Private Sub Animal_Mover(ByVal Distance As Double)
	' (Se omite el código de la zancada.)
	Debug.Print "Tiranosaurio movido"
End Sub

Private Sub Animal_Morder(ByVal What As Object)
	' (Se omite el código de la dentellada.)
	Debug.Print "El Tiranosaurio ha mordido un " & TypeName(What)
End Sub
 

 

Pruebas con el Tiranosaurio y la Pulga

Agregue el código siguiente al evento Load de Form1:

Private Sub Form_Load()
	Dim fl As Pulga
	Dim ty As Tiranosaurio
	Dim anim As Animal

	Set fl = New Pulga
	Set ty = New Tiranosaurio
	' Primero juega la pulga.
	Set anim = fl
	Call anim.Morder(ty)	' La pulga muerde al 
								' dinosaurio.
	' Ahora es el turno del Tiranosaurio.
	Set anim = ty
	Call anim.Morder(fl)	' El dinosaurio muerde a
								' la pulga.
End Sub
 

 

Presione F8 para recorrer el código. Observe los mensajes de la ventana Inmediato. Cuando la variable anim contiene una referencia a Pulga, se invoca la implementación de Morder de Pulga, y de la misma forma para Tiranosaurio.

La variable anim puede contener una referencia a cualquier objeto que implemente la interfaz Animal. De hecho, sólo puede contener referencias a dichos objetos. Si intenta asignar un objeto Form o PictureBox a anim, se producirá un error.

El método Morder se enlaza en tiempo de diseño cuando lo llama mediante anim, puesto que Visual Basic sabe en tiempo de compilación que cualquier objeto asignado a anim tendrá un método Morder.

Paso de Tiranosaurios y Pulgas a procedimientos

Recuerde el procedimiento Alimentarse de “¿Cómo proporciona Visual Basic el polimorfismo?”. Puede agregar la segunda versión del procedimiento Alimentarse (el que ilustra el polimorfismo) a Form1 y sustituir el código del evento Load por el siguiente:

Private Sub Form_Load()
	Dim fl As Pulga
	Dim ty As Tiranosaurio

	Set fl = New Pulga
	Set ty = New Tiranosaurio
	'La pulga se come al dinosaurio.
	Call Alimentarse(fl, ty)
	' Y viceversa.
	Call Alimentarse(ty, fl)
End Sub
 

 

El repaso de este código muestra cómo una referencia de objeto pasada a un argumento de otro tipo de interfaz se convierte en referencia a la segunda interfaz (en este caso, Animal). Lo que ocurre es que Visual Basic consulta el objeto para saber si acepta la segunda interfaz. Si el objeto lo acepta, devuelve una referencia a la interfaz y Visual Basic coloca esa referencia en la variable del argumento. Si el objeto no acepta la segunda interfaz, se produce un error.

 

Implementación de métodos que devuelven valores

Suponga que el método Mover devolviera un valor. Después de todo, sabe cuánto quiere que se mueva el Animal, pero un espécimen concreto podría no ser capaz de llegar tan lejos. Podría estar viejo y decrépito o podría haber un muro en su camino. Puede utilizar el valor devuelto por el método Mover para saber indicarle el movimiento real del Animal.

Public Function Mover(ByVal Distance As Double) As Double

End Function

 

Cuando implemente este método en la clase Tiranosaurio, asigne el valor devuelto al nombre del procedimiento, como lo haría en cualquier otro procedimiento Function:

Private Function Animal_Mover(ByVal Distance _
As Double) As Double
	Dim dblDistanceMoved As Double
	' Código para calcular la distancia (basado en
	' edad, salud y obstáculos) omitido).
	' Este ejemplo asume que el resultado se encuentra 
	' en la variable dblDistanceMoved.
	Debug.Print "Tiranosaurio movido "; 
	dblDistanceMoved
	Animal_Mover = dblDistanceMoved
End Function
 

 

Para asignar el valor devuelto, utilice el nombre completo del procedimiento, incluido el prefijo de la interfaz.

Para obtener más información Las interfaces que implemente pueden tener propiedades y métodos. En “Implementación de propiedades” se describen algunas diferencias en la forma de implementar las propiedades.

 


4 - Implementación de propiedades

 

En este tema continúa el ejemplo de código empezado en “Creación e implementación de una interfaz” y se agregan propiedades a la interfaz Animal implementada en las clases Pulga y Tiranosaurio. Puede que le interese leer dicho tema antes de empezar éste.

Suponga que incluye una propiedad Edad en la clase Animal mediante una variable Public en la sección Declaraciones:

Option Explicit
Public Edad As Double

 

Las listas desplegables Procedimiento de los módulos de código de las clases Tiranosaurio y Pulga contienen ahora procedimientos de propiedad para implementar la propiedad Edad, como se muestra en la figura 9.10.

Figura 9.10 Implementación de los procedimientos de propiedad

 

Esta figura ilustra una característica mencionada en “Agregar propiedades a una clase”, anteriormente en este tema. El empleo de una variable pública para implementar una propiedad es estrictamente una comodidad para el programador. Internamente, Visual Basic implementa las propiedades como parejas de procedimientos de propiedad.

Debe implementar ambos procedimientos. Los procedimientos de propiedad se implementan fácilmente si almacena el valor en un miembro privado de datos, como se puede ver a continuación:

Private mdblEdad As Double


Private Property Get Animal_Edad() As Double
	Animal_Edad = mdblEdad
End Property


Private Property Let Animal_Edad(ByVal RhsVal As Double)
	mdblEdad = RhsVal
End Property 

 

El miembro privado de datos es un detalle de la implementación, de modo que tiene que agregarlo manualmente.

Nota Cuando Implements proporciona la plantilla de un Property Set o un Property Let, no hay manera de determinar el nombre del último argumento, de forma que sustituye el nombre RhsVal, como se ve en el ejemplo anterior.

No hay validación de datos en una propiedad implementada como miembro público de datos, pero esto no significa que no pueda agregar código de validación en el procedimiento Property Let de Animal_Edad. Por ejemplo, puede que desee restringir los valores de las edades apropiadas para un Tiranosaurio o para una Pulga, respectivamente.

De hecho, esto demuestra la independencia de la interfaz y de la implementación. Siempre y cuando la interfaz coincida con la descripción de la biblioteca de tipos, la implementación puede realizarse de cualquier modo.
Antes de ir al paso siguiente, quite la implementación de la propiedad Edad para lectura y escritura de ambos módulos de clase.

 

Implementación de una propiedad de sólo lectura

Por supuesto, la posibilidad de permitir que la edad de un animal pueda establecerse de forma arbitraria es un mal diseño del objeto. El objeto tiene que saber su edad y proporcionarla al usuario como propiedad de sólo lectura. Quite la variable pública Edad de la clase Animal y agregue la plantilla de la propiedad de sólo lectura Edad, de esta forma:

Public Property Get Edad() As Double

End Property

 

Ahora, las listas desplegables Procedimiento de las ventanas Código de las clases Tiranosaurio y Pulga sólo contienen una entrada, Edad [PropertyGet]. Podría implementarla para el objeto Tiranosaurio de la manera siguiente:

Private mdblBirth As Double

Private Property Get Animal_Edad() As Double
	Animal_Edad = Now - mdblBirth
End Property 

 

El código anterior devuelve la edad del Tiranosaurio en días. Podría establecer mdblBirth en el evento Initialize de la clase Tiranosaurio, como se muestra a continuación:

Private Sub Class_Initialize()
mdblBirth = Now
End Sub

 

Desde luego, podría devolver el valor de la propiedad en unidades más comunes, como años.

Para obtener más información Se han tratado las interfaces y los objetos como si fueran iguales, con el cuidado de poner las referencias a los objetos en una variable de objeto y las referencias a las interfaces en otra. En “Tiempo muerto para una breve descripción de objetos e interfaces” se aclaran las diferencias.

 


5 - Tiempo muerto para una breve descripción de objetos e interfaces

 

En este tema termina el ejemplo de código empezado en “Creación e implementación de una interfaz” y continuado en “Implementar propiedades”. Puede que le interese ver dichos temas antes de empezar éste.

El ejemplo de código de Tiranosaurio y Pulga parece tratar con comodidad las interfaces y los objetos. Las referencias a objetos se asignan a una variable de objeto y las referencias a interfaces a otra.

De hecho, todas las referencias son referencias de objeto. Una referencia a una interfaz también es una referencia al objeto que implementa la interfaz. Además, un objeto puede tener múltiples interfaces y seguir siendo el mismo objeto con todas ellas.

En Visual Basic, cada clase tiene una interfaz predeterminada con el mismo nombre que la clase. Es casi lo mismo. Por convención se escribe un carácter de subrayado como prefijo del nombre de clase. El subrayado indica que esta interfaz se encuentra oculta en la biblioteca de tipos.

De esta forma, la clase Tiranosaurio tiene una interfaz predeterminada llamada _Tiranosaurio. Como esta clase también implementa la interfaz Animal, tiene una segunda interfaz llamada Animal.

Sin embargo, debajo de todas ellas el objeto sigue siendo un Tiranosaurio. Coloque un botón de comando en Form1 y agregue el código siguiente:

Private Sub Command1_Click()
	Dim ty As Tiranosaurio
	Dim anim As Animal

	Set ty = New Tiranosaurio
	Set anim = ty
	MsgBox TypeName(anim)
End Sub 

 

Consulta de las interfaces

Cuando asigna un objeto Tiranosaurio a una variable de tipo Animal, Visual Basic pregunta al objeto Tiranosaurio si acepta la interfaz Animal. (El método utilizado recibe el nombre de QueryInterface o su abreviatura, QI; puede que algunas veces se encuentre QI utilizado como verbo.) Si la respuesta es no, se produce un error.

Si la respuesta es sí, el objeto se asigna a la variable. A través de dicha variable sólo se puede tener acceso a los métodos y propiedades de la interfaz Animal.

Variables genéricas de objeto e interfaces

¿Qué ocurre si asigna una referencia de objeto a una variable genérica de objeto, como en el código siguiente?

Private Sub Command1_Click()


	Dim ty As Tiranosaurio
	Dim anim As Animal
	Dim obj As Object


	Set ty = New Tiranosaurio
	Set anim = ty
	Set obj = anim


	MsgBox TypeName(obj)


End Sub 

 

El resultado vuelve a ser un objeto Tiranosaurio. Y ahora, ¿qué interfaz obtiene cuando llama a las propiedades y los métodos mediante la variable obj? Agregue el método siguiente a la clase siguiente Tiranosaurio:

Public Sub Rugir()
	Debug.Print "Rrrrrr"
End Sub 

 

El método Rugir pertenece a la interfaz predeterminada del objeto Tiranosaurio. En el código del evento Click del botón de comando, sustituya la instrucción MsgBox por las dos líneas de código siguientes:

obj.Mover 42
obj.Rugir

Cuando ejecuta el proyecto y hace clic en el botón, la ejecución se detiene en el método Rugir, con el error “El objeto no acepta esta propiedad o método”. Está claro que la interfaz sigue siendo Animal.

Debe tener esto en cuenta cuando utilice variables de tipo Object con objetos que tienen múltiples interfaces. La interfaz a la que tiene acceso la variable es la última interfaz asignada.

Por ejemplo:

Private Sub Command1_Click()
	Dim ty As Tiranosaurio
	Dim anim As Animal
	Dim obj As Object

	Set ty = New Tiranosaurio
	Set anim = ty
	Set obj = anim
	obj.Mover 42		' Correcto
	obj.Rugir			' Erróneo

	Set obj = ty
	obj.Mover 42		' Erróneo
	obj.Rugir			' Correcto
End Sub 

 

Afortunadamente, no hay muchas razones a favor de utilizar los tipos de datos Object enlazados en tiempo de compilación, que son lentos, con los objetos que tienen múltiples interfaces. Una de las principales razones a favor del empleo de múltiples interfaces es la ventaja de disponer de enlaces en tiempo de diseño mediante el polimorfismo.

 

Otros orígenes de interfaces

Los módulos de clase de Visual Basic no son el único origen de interfaces implementables. Puede implementar cualquier interfaz contenida en una biblioteca de tipos si dicha interfaz acepta Automatización.

Si tiene la Edición profesional o la Edición empresarial de Visual Basic, puede crear sus propias bibliotecas de tipos de clases abstractas. Dichas bibliotecas de tipos se pueden utilizar en muchos proyectos, como se describe en el tema “Principios generales del diseño de componentes” de Crear componentes ActiveX, en la Guía de herramientas componentes.

La Edición profesional y la Edición empresarial también incluyen el programa MkTypLib (Generar biblioteca de tipos) en el directorio Tools. Si ha utilizado este programa en Microsoft Visual C++, puede que le parezca una manera más apropiada para crear interfaces.

 

Uso de interfaces en el proyecto

Para utilizar una interfaz en el proyecto, haga clic en Referencias en el menú Proyecto para abrir el cuadro de diálogo Referencias. Si registró la biblioteca de tipos, aparecerá en la lista de referencias y podrá seleccionarla. Si la biblioteca de tipos no se encuentra en la lista, puede utilizar el botón Examinar para buscarla.

En cuanto tenga una referencia a una biblioteca de tipos, puede utilizar Implements para implementar cualquiera de las interfaces de Automatización contenidas en la biblioteca de tipos.

Para obtener más información No está limitado a implementar interfaces abstractas. En “Múltiples facetas (e interfaces) de la reutilización del código” se describe cómo puede implementar una interfaz y reutilizar selectivamente las propiedades y los métodos de la clase que proporciona la interfaz.

 


6 - Múltiples facetas (e interfaces) de la reutilización del código

 

Existen principalmente dos formas de reutilización del código: binario y origen. La reutilización de código binario se consigue mediante la creación y uso de un objeto, mientras que la reutilización de código de origen se consigue por herencia, lo que no se permite en Visual Basic. (La reutilización de código de origen también se puede conseguir mediante la copia y modificación del código de origen, pero esta técnica no es nada nuevo y conlleva muchos problemas ya conocidos.)
Visual Basic ha sido uno de los pioneros en la reutilización de código binario; los controles son el ejemplo más clásico. Puede volver a utilizar el código de un control si coloca una instancia del control en un formulario. Esto se conoce como relación de contenedor o de posesión; por ejemplo, el formulario contiene o posee un control CommandButton.
Para obtener más información Las relaciones de contenedores se describen en “Modelos de objetos”, más adelante en este tema.

 

Delegación en un objeto implementado

Implements proporciona un medio eficaz para volver a utilizar el código. Puede implementar una clase abstracta (como se describe en “Creación e implementación de una interfaz”) o puede implementar la interfaz de una clase totalmente funcional. Puede crear el objeto interno (es decir, el objeto implementado) en el evento Initialize del objeto externo (el que implementa la interfaz del objeto interno).

Como se menciona en “Creación e implementación de una interfaz”, una interfaz es como un contrato: tiene que implementar todos los miembros de la interfaz del objeto interno en el módulo de clase del objeto externo. Sin embargo, puede ser muy selectivo en la forma en que delega en las propiedades y los métodos del objeto interno. En un método podría delegar directamente en el objeto interno, mediante el paso de argumentos sin modificar, mientras que en otro método podría ejecutar parte del código antes de llamar al objeto interno y en un tercer método podría ejecutar únicamente su propio código y pasar por alto completamente el del objeto interno.

Por ejemplo, suponga que tiene una clase HombreOrquesta y una clase Cacofonía que generan sonidos. Le gustaría agregar la funcionalidad de la clase Cacofonía a la clase HombreOrquesta y reutilizar parte de la implementación de los métodos de la clase Cacofonía.

' HombreOrquesta implementa la interfaz Cacofonía.
Implements Cacofonía

' Variable de objeto para mantener la referencia.
Private mcac As Cacofonía

Private Sub Class_Initialize()
	' Crea el objeto.
	Set mcac = New Cacofonía
End Sub 

 

Ahora puede ir a la lista desplegable Objeto, seleccionar Cacofonía y después obtener las plantillas de procedimiento para los métodos de la interfaz Cacofonía. Para implementar dichos métodos, puede delegar en el objeto Cacofonía. Por ejemplo, el método Beep podría tener la apariencia siguiente:

Private Sub Cacofonía_Beep(ByVal Frequency As Double, _
ByVal Duration As Double)
	' Delega en el objeto interno Cacofonía.
	Call mcac.Beep(Frequency, Duration)
End Sub 

 

La implementación anterior es muy sencilla. El objeto externo (HombreOrquesta) delega directamente en el interno (Cacofonía) y vuelve a utilizar el método Beep del objeto Cacofonía sin modificarlo. Esto está muy bien, pero es sólo el principio.

La instrucción Implements es una herramienta de reutilización de código muy eficaz, puesto que ofrece gran flexibilidad. Puede que decida alterar el efecto del método Beep de la clase HombreOrquesta. Para ello, inserte su propio código antes (o después) de la llamada al objeto interno Cacofonía:

Private Sub Cacofonía_Beep(ByVal Frequency As Double, _
ByVal Duration As Double)
	' Eleva las notas una octava.
	Frequency = Frequency * 2
	' Basado en otra propiedad de la clase 
	' HombreOrquesta, Staccato, acorta la duración de 
	' cada nota.
	If Staccato Then Duration = Duration * 7 / 8
	Call mcac.Beep(Frequency, Duration)
	' Incluso puede llamar a otros métodos de 
	' HombreOrquesta.
	If Staccato Then Pause(Duration * 1 / 8)
End Sub 

 

En algunos de los métodos, la implementación puede delegar directamente en el objeto interno Cacofonía, mientras que en otros puede interponer su propio código antes y después de delegar o incluso omitir la delegación si sólo utiliza su propio código para implementar un método.

Como la clase HombreOrquesta implementa la interfaz Cacofonía, puede utilizarla con cualquier aplicación musical que llame a dicha interfaz. Los detalles de la implementación están ocultos para la aplicación que llama, pero los sonidos resultantes son los diseñados por usted.

Nota COM proporciona otro mecanismo para la reutilización de código binario, llamado agregación. En la agregación se utiliza una interfaz completa sin modificaciones y la implementación la proporciona una instancia de la clase agregada. Visual Basic no acepta esta forma de reutilización de código.

¿No es tedioso?

La escritura de código de delegación puede resultar muy tediosa, especialmente si la mayor parte de las propiedades y los métodos del objeto externo simplemente delegan de forma directa en las propiedades y los métodos correspondientes del objeto interno.

Si tiene la Edición profesional o la Edición empresarial de Visual Basic, puede utilizar el Modelo de extensibilidad de Visual Basic para crear su propio asistente de delegación y automatizar la tarea, que es similar al Asistente de clases incluido en la Edición profesional y en la Edición empresarial.

Para obtener más información El uso del polimorfismo y de las interfaces múltiples en los componentes software se describe en “Principios generales del diseño de componentes” de la sección Crear componentes ActiveX de la Guía de herramientas componentes.
El uso del Modelo de extensibilidad está documentado en Ampliación del entorno de desarrollo de Visual Basic con complementos, en la Guía de herramientas componentes.

 

 

 


Volver al índice

 

 


Buscar en Recursos vb