Saltar al contenido

herencia VBA, análogo de super

Joel, parte de nuestro equipo de trabajo, nos hizo el favor de redactar este tutorial ya que controla perfectamente el tema.

Solución:

La forma habitual de hacer esto en VBA es hacer que A contenga una instancia de B, además de que A implemente la interfaz de B, y luego delegue las llamadas a la interfaz B de A a la B interna.

Esto es algo antiguo, pero consulte la Guía del programador de Visual Studio 6.0:

http://msdn.microsoft.com/en-us/library/aa716285(VS.60).aspx

Hay un capítulo sobre “Las muchas (inter) caras de la reutilización de código” que describe esta convención:

http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx

La forma en que MS lo describe es:

Además de implementar interfaces abstractas, puede reutilizar su código implementando la interfaz de una clase ordinaria y luego delegando selectivamente a una instancia oculta de la clase.

Esto significa que la herencia de implementación requiere muchos métodos de delegación explícitos. Incluso hay un subtítulo de capítulo: “¿Esto no se vuelve tedioso?”. Otra razón más por la que OOP en VBA es un PITA (TM)…

EDIT QUE NO CABE EN UN COMENTARIO:

Para responder a la pregunta que planteó en su comentario, bueno, una A es a B. Cuando hace que A implemente la interfaz de B, esencialmente está diciendo que puede tratar una instancia de A como si fuera realmente del tipo B. En VBA, la forma de hacerlo es declarando una variable de tipo B, y luego configurándolo en una instancia de A. VBA sabrá qué hacer cuando lo llame como una B:

Dim usedAsB as B
Dim anA as A

Set anA = New A
Set usedAsB = anA    'fine since A implements B

usedAsB.something()    'will call B_something() defined in class A

En cuanto a lo que ve en la ventana de depuración, no sé por qué aparece de esa manera. Y en cuanto a la delegación forzada, no estoy seguro de lo que quieres decir. VBA envía automáticamente llamadas a la interfaz B a los métodos correctos en la clase A. Si quiere decir generar automáticamente el código para heredar la implementación de B de la manera descrita anteriormente, no hay nada de eso que yo sepa para VBA. Creo que las diversas versiones “profesionales” de VB6 podrían hacer eso, pero nunca he usado VB6, así que no lo sé.

Esta es la forma en que lo he usado durante mucho tiempo para simular una clase abstracta a través de la interfaz.

'class module: IBase
'We define a base interface
'
Sub go(): End Sub

Sub gogo(): End Sub

Ahora definamos las otras clases, comenzando con la clase abstracta ‘B’.

'
'class module: B
'
Implements IBase

'Daughter classes should implement 'go'
'Note that the method is 'Public'
Public Sub go(): End Sub

'Let's agree that every daughter class implements the method
'abstract 'super' that returns the IBase interface
Public Property Get super() As IBase: End Property

'
'The signature of other abstract methods can be stated here
'
'Public Sub goGoChild(): End Sub
'Public Function goGoGoChild2(): End Function
'

'
'Note that the methods are accessible through the IBase interface
'
Private Sub IBase_go()
    Debug.Print "B: super.go()"
End Sub

Private Sub IBase_gogo()
    Debug.Print "B: super.gogo()"
End Sub

Creemos la clase ‘A’ que implementa la clase abstracta ‘B’

'
'class module: 'A'
'

'We started implementing the abstract class B
Implements B

'we define a private type 'myType'
Private Type myType

    'variable that references an instance of 'B'
    objB As B

    'variable that references the interface of 'B'
    objIB As IBase

End Type

'VBA version of 'this'
Private this As myType

'
'Every class that implements 'B' (abstract class)
'you must initialize in your constructor some variables
'of instance.
'
Private Sub Class_Initialize()

    With this

        'we create an instance of object B
        Set .objB = New B

        'the variable 'objIB' refers to the IBase interface, implemented by class B
        Set .objIB = .objB

    End With

End Sub


'Visible only for those who reference interface B
Private Property Get B_super() As IBase

    'returns the methods implemented by 'B', through the interface IBase
    Set B_super = this.objIB

End Property

Private Sub B_go()
    Debug.Print "A: go()"
End Sub
'==================================================

'Class 'A' local method
Sub localMethod1()
    Debug.Print "A: Local method 1"
End Sub

Y finalmente, creemos el módulo ‘principal’.

Sub testA()

    'reference to class 'A'
    Dim objA As A

    'reference to interface 'B'
    Dim objIA As B

    'we create an instance of 'A'
    Set objA = New A

    'we access the local methods of instance 'A'
    objA.localMethod1

    'we obtain the reference to interface B (abstract class) implemented by 'A'
    Set objIA = objA

    'we access the 'go' method, implemented by interface 'B'
    objIA.go

    'we go to the 'go' method of the super class
    objIA.super.go

    'we access the 'gogo' method of the super class
    objIA.super.gogo

End Sub

Y el resultado, en la ventana de verificación, será:

A: Local method 1
A: go()
B: super.go()
B: super.gogo()

ingrese la descripción de la imagen aquí

Te mostramos reseñas y puntuaciones

Más adelante puedes encontrar las interpretaciones de otros usuarios, tú incluso tienes el poder mostrar el tuyo si te apetece.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *