Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop users from instancing an interface and not its implementation

Tags:

excel

vba

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 returning False. 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.

like image 271
Matteo NNZ Avatar asked Jan 27 '26 01:01

Matteo NNZ


1 Answers

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.

like image 113
Mathieu Guindon Avatar answered Jan 29 '26 13:01

Mathieu Guindon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!