For a personal project I prepare some interfaces in a VBA workbook which (being interfaces) are supposed to be implemented by the final users.
If I was coding in a language like Java, I wouldn't be able to instantiate an interface as the compiler would stop me:
Greetings.java
public interface Greetings {
public String sayHello(String person);
}
GreetingsImpl.java
public class GreetingsImpl implements Greetings {
@Override
public String sayHello(String person) {
return "Hello " + person;
}
}
Code
Greetings greets = new GreetingsImpl(); //<-- OK
Greetings greets = new Greetings(); //<-- ERROR: Greetings is abstract; cannot be instantiated
However, in VBA I've noticed that you can instantiate an Interface, and the method would run as if it was called (just returning the default value).
IGreetings
Public Function sayHello(person As String) As String
End Function
Greetings
Implements IGreetings
Public Function IGreetings_sayHello(person As String) As String
IGreetings_sayHello = "Hello " & person
End Function
Code
Dim greets As IGreetings
Set greets = New Greetings
MsgBox greets.sayHello("Matteo") '<-- it works
Set greets = New IGreetings
MsgBox greets.sayHello("Matteo") '<-- it shows empty, but it works
Is there any way I can refrain such a mistake on interface side, or should I just see it as a limitation of VBA?
Note: even though this issue may seem absurd/useless, it actually happened in real life. There was a method of an interface which was supposed to evaluate some parameters and return a
Boolean. One of the clients implemented the logic but then he instantiated the interface instead of its implementation, and the method was always returningFalse. The code ran in production before they figured out it was always returning false, and it took some time to figure that out, I would like to know if I can avoid somehow else than just highlighting this in the documentation or relying on users care.
It's not a limitation of VBA, it's a feature of Classic VB: every single class defines an interface - the class' default interface: that's how any class can implement any other.
There is therefore no way to get a compile-time error for this.
Static code analysis tools can help though. Rubberduck's Implemented Interface Member inspection warns about interface members that have an implementation (the code examples on that page probably need to be made clearer though), but that doesn't warn when the interface is instantiated... we could pretty easily implement an inspection that warns about instantiated interface classes though.
Other than that, you can get a run-time error for New-ing up what's intended as an abstract interface, by throwing an error in the Class_Initialize handler, as Freeflow suggested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With