VBA inheritance, analog of super

Viewed 37320

For example I have class A which implements class B

---class A----

implements B
public sub B_do()
end sub

--class B----

public sub do()
end sub

How can I call do() from A? (super.do()) So, how I can define some common variable for both classes? Now I can inherit only functions, sub and properties...

added: same question http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/5a83d794-3da1-466a-83d3-5d2eb0a054b2

added: It is not possible to share variable across hierarhy of classes. You should implements property (same way as functions).

3 Answers

This is the way I have used it a long time to simulate an abstract class through the interface.

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

Sub gogo(): End Sub

Now let's define the other classes, beginning with the abstract class '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

Let's create class 'A' which implements the abstract class '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

And finally, let's create the 'main' module.

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

And the output, in the verification window, will be:

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

enter image description here

One can pull a trick to mimic inheritance. It works by using the default member property.

If you give your derived class a property called Super whose type is the superclass then make that the default member (by exporting and editing file to include Attribute Item.VB_UserMemId = 0, re-importing) then you can reach the superclass by just a pair of round brackets (which resolves to the default member).

This blog post gives the full details but author (disclosure, me) there uses 'Base' instead of 'Super'

Hopefully that syntax is tight enough for you.

I also point out that this does not expose all the base class's internal guts like C# does. This means my method does not suffer from the fragile base class problem. I.e. my method retains encapsulation making it better IMHO.

Related