5

I'm working with some legacy code in Visual Basic 98, and there are several classes with an "I" in front of their name. Most of the classes don't have this name, however.

Here's the contents of the IXMLSerializable.cls file.

' Serialization XML:
'       Create and receive complete split data through XML node
Public Property Let SerializationXML(ByVal p_sXML As String)
End Property
Public Property Get SerializationXML() As String
End Property

Public Property Get SerializationXMLElement() As IXMLDOMElement
End Property
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120
Joshua McVey
  • 86
  • 1
  • 6
  • 7
    Because they aren´t classes, but **Interfaces**. – MakePeaceGreatAgain Jun 05 '19 at 13:57
  • 3
    https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/ – Alex K. Jun 05 '19 at 13:58
  • Possibly also see https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms760248(v%3Dvs.85) for more information on IXMLDOMElement – JamesS Jun 05 '19 at 13:59
  • As naming convention interfaces have their names starting with an upper case "i". – Flavio Francisco Jun 05 '19 at 14:00
  • Interfaces provide an abstraction layer and help decouple components of an application, through polymorphism. The code works with an `IXMLSerializable` object, without needing to care for the actual implementation - it's guaranteed to be an object that exposes a `SerializationXML` string property and a getter for an `SerializationXMLElement` property; *how* that's implemented is irrelevant to the caller. This is useful for *a lot* of things in OOP, and yes, [VB6 & VBA can do OOP](https://stackoverflow.com/a/31861832/1188513). – Mathieu Guindon Jun 05 '19 at 14:29

3 Answers3

4

Note that VBA supports interfaces, just as C#/VB.NET do (almost). Interfaces are the only way to provide inheritance mechanisms in VBA.

By convention interfaces start their name with the capital letter I.

Here is an example interface declaration that states an object must define a name property

[File: IHasName.cls, Instancing: PublicNotCreatable] 
Option Explicit

Public Property Get Name() As String
End Property

As you can see there is no implementation required.

Now to create an object that uses the interface to advertise that it contains a name property. Of course, the point is that there are multiple classes that use the one interface.

[File: Person.cls, Instancing: Private]
Option Explicit
Implements IHasName

Private m_name As String

Private Sub Class_Initialize()
    m_name = "<Empty>"
End Sub

' Local property
Public Property Get Name() as String
    Name = m_name
End Property

Public Property Let Name(ByVal x As String)
    m_name = x
End Property

' This is the interface implementation that relies on local the property `Name` 
Private Property Get IHasName_Name() As String
    IHasName_Name = Name
End Property

As a convenience in the UI once you include the Implements statement you can choose the interface properties from the top

scr

And to consume the above code use the following test, which calls a function that can take any object that implements IHasName.

[File: Module1.bas]
Option Explicit

Public Sub TestInterface()

    Dim target As New Person
    target.Name = "John"

    GenReport target
    ' This prints the name "John".
End Sub

Public Function GenReport(ByVal obj As IHasName)
    Debug.Print obj.Name
End Function
John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • 1
    *the point is that there are multiple classes that use the one interface* - not necessarily. I see it more as changing the color of the lens through which we look at a given object: I can have a `Person` class with a default instance that exposes a `Create` factory method and `Get`+`Let` accessors for a `Name` property; the class implemens `IPerson` which only exposes the `Get` accessor, and the rest of the code works off the effectively read-only `IPerson`. The number of classes that implement an interface is irrelevant IMO. – Mathieu Guindon Jun 05 '19 at 15:55
  • @MathieuGuindon - yes, an interface can be a level of abstraction for properties and methods which themselves are a level of abstraction from fields. As far as API go like `IXmlDomElement`, there seems to be a place for interfaces in restricting access to the underlying class. – John Alexiou Jun 05 '19 at 16:26
  • Interfaces are the only way to provide abstraction, not inheritance and the VBA language doesn't come with a convention for naming interfaces. The convention from your answer is from .NET, not VBA. See [Implements statement](https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/implements-statement). – Florent B. Jun 06 '19 at 13:15
3

The I stands for Interface, like specified in the Microsoft Official Documentation:

IXMLDOMElement Members.

The following tables show the properties, methods, and events.

In C++, this interface inherits from IXMLDOMNode.

That was a pretty common convention and by doing so, you immediately know that it represent an Interface, without looking at the code.

Hope this helps.

Louis
  • 3,592
  • 2
  • 10
  • 18
1

I stands for interface. VBA and older Visual Basic dialects up to VB 6.0 are said to be object oriented but a have a very poor support for it. For example, there is no class inheritance. Nevertheless, you can declare and implement interfaces in VBA/VB6; however, there is no Interface keyword as there is a Class keyword. Instead, you just declare a class with empty Subs, Functions and Properties.

Example. In a Class named IComparable, declare a Function CompareTo:

Public Function CompareTo(ByVal other As Object) As Long
    'Must return -1, 0 or +1, if current object is less than, equal to or greater than obj.
    'Must be empty here.
End Function

Now you can declare classes that implement this interface. E.g. a Class named clsDocument:

Implements IComparer

public Name as String

Private Function IComparable_CompareTo(other As Variant) As Long
    IComparable_CompareTo = StrComp(Name, other.Name, vbTextCompare)
End Function

Now, this lets you create search and sorting algorithms that you can apply to different class types that implement this method. Example of a class called Document

Option Explicit

Implements IComparable

Public Name As String
Public FileDate As Date

Public Function IComparable_CompareTo(ByVal other As Object) As Long
    Dim doc As Document, comp As Long

    Set doc = other
    comp = StrComp(Me.Name, doc.Name, vbTextCompare)
    If comp = 0 Then
        If Me.FileDate < doc.FileDate Then
            IComparable_CompareTo = -1
        ElseIf Me.FileDate > doc.FileDate Then
            IComparable_CompareTo = + 1
        Else
            IComparable_CompareTo = 0
        End If
    Else
        IComparable_CompareTo = comp
    End If
End Function

Here an example of a QuickSort for VBA. It assumes that you pass it an array of IComparables:

Public Sub QuickSort(ByRef a() As IComparable)
'Sorts a unidimensional array of IComparable's in ascending order very quickly.
    Dim l As Long, u As Long

    l = LBound(a)
    u = UBound(a)
    If u > l Then
        QS a, l, u
    End If
End Sub

Private Sub QS(ByRef a() As IComparable, ByVal Low As Long, ByVal HI As Long)
'Very fast sort: n Log n comparisons
    Dim i As Long, j As Long, w As IComparable, x As IComparable

    i = Low:   j = HI
    Set x = a((Low + HI) \ 2)
    Do
        While a(i).CompareTo(x) = -1:   i = i + 1:   Wend
        While a(j).CompareTo(x) = 1:   j = j - 1:   Wend
        If i <= j Then
            Set w = a(i):   Set a(i) = a(j):   Set a(j) = w
            i = i + 1:   j = j - 1
        End If
    Loop Until i > j
    If Low < j Then QS a, Low, j
    If HI > i Then QS a, i, HI
End Sub
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • 1
    I am not a VBA hater. I have done a lot of cool things with it. But since I am programming in VB.NET and C#, I don't want to go back to VBA. OO design is a principle that you can even apply to languages not having classes etc. I do not pretend that you cannot write good OOP code in VBA/VB6, just the support is not comparable to the one you have in VB.NET/C#. No inheritance, no constructors, limited type system. Where are `List(Of T)`, `Dictionary(Of K, V)` etc. `Collection` is a monster trying to implement both of them but having a lot of limitations. `On Error Resume Next` ugh! – Olivier Jacot-Descombes Jun 05 '19 at 15:22
  • I didn't mean to call *you* a VBA hater - that didn't come across as I intended, sorry. Constructors have nothing to do with OOP capabilities, and factories work beautifully in VBA/VB6 to achieve the same purpose (parameterized initialization of an object). The amazing type system in .NET, with generics (`Of T`), only appeared in .NET 2.0; before that, you had `ArrayList`, which was the very same kind of monster `Collection` is, plus all the value-type boxing penalties. OERN, absolutely agree, but that again has nothing to do with OOP. Comparing C# 7 /current VB to VB6 is just unfair ;-) – Mathieu Guindon Jun 05 '19 at 15:33