What is an interface?
An interface is the set of methods, messages, or VIs (think connector panes) that we use to pass data in and out of a software module. Simply put, what are the inputs and outputs, and how do they get in and out? A software module could be a class, a library, or simply a repository of VIs (in descending order of author preference).
Why are interfaces useful?
With thoughtfully designed software (presently focusing on good interfaces), we can actually achieve the modularity and reusability that might have historically been more of a good idea than an actual work practice. If all inputs and outputs in two functionally equivalent software modules are of the same type and in the same place, our code is—wait for it—actually modular!
How do I make an interface?
Object-oriented programming gives us a leg up here! By using inheritance, we can create a class whose sole purpose is to define an interface for all of its children. To make its purpose clear, we can call this class an Abstract Parent Interface Class and name it with a leading “I”.
Caveat: The topic of software interfaces is nuanced. While the approach shown below can be very helpful, it will not address all of our interface needs (perhaps more on that in another post).
Consider this snippet of a class hierarchy showing message transport abstraction:
The parent class is called IMessageTransport and defines an interface that all children must implement to manage the transportation of messages (Send). The parent interface class also defines methods (Read, Close) that only some of its children must implement.
If we want to enforce rules for children of our parent interface class, we can use two checkboxes in the abstract parent interface class’s properties dialog:
Require descendant classes to override this dynamic dispatch VI—
Use this checkbox to force a child to implement a parent’s interface method. (As the label implies, we call this overriding a method.)
Require overrides of this dynamic dispatch VI to always invoke the Call Parent Method node—
Use this checkbox to require that a child’s override also call its parent’s method. (We call this extending a method since the child does its parent's function and something extra.)
Note that our code will be broken at edit time until all child classes fulfill the obligations captured in these checkboxes—but one might claim that’s a good thing! In the IMessageTransport example, all children must override the Send, but only some override the Read and Close methods. (For example, we can’t tell an actor to read—it handles that on its own!)
Aren’t interfaces first-class citizens in other programming languages?
Some languages allow the developer to differentiate between a class and an interface, but lack of one special checkbox in LabVIEW is not a good reason to ignore an important programming concept. Considering interfaces in LabVIEW helps us write code that is more reusable and easier to understand. If there’s a chance I might inherit your code one day, I hope you agree.