Understanding Interfaces in VB.NET

By Peter A. Bromberg, Ph.D.
Printer-Friendly Version

Peter Bromberg

The underlying backbone of COM is the concept of Interfaces. COM - based classes simply cannot be created without them. Of course, millions of VB 6.0 programmers have been happily creating COM - based ActiveX DLL's and controls without knowing diddlysquat about interface - based OOP programming, simply because all the interface - based COM infrastructure and plumbing is done by VB automatically "behind the scenes". However in VB.NET, interfaces become visible, full-fledged citizens, and consequently deserve some study.

What's an Interface?

An Interface is a collection of semantically - related methods that describe a unique behavior that is to be supported by a class. Interface - based programming encourages the reuse of behavior. Once you've defined an interface, more than one class can choose to implement its functionality. An interface in VB.NET always contains abstract members. For example,

Public Interface ICardAccount
Function GetBalance(AccountNumber as Integer) as Decimal
Property MaxCashAdvance() as Decimal

End Interface

Note that the method and property signatures are defined, but they are abstract. The implementation is up to the class that wishes to inherit the interface. Unlike abstract base classes, interfaces never define data members, and they never provide a default implementation.

When you consider the fact that VB.NET (and most .NET languages, except perhaps Eiffel) only support single inheritance, interface-based programming enables a type to support a number of behaviors while simplifying the issues that could arise from multiple base class inheritance.

In VB.NET, when we want to extend the functionality of a given class, we do so with the Implements keyword. So for example, if we had a class SuperCardAccount, we could implement the ICardAccount interface like this:

Public Class SuperCardAccount : Inherits Account
Implements ICardAccount
Public Sub New()
End Sub
Public Sub New(ByVal AccountName as String)
End Sub
' Implement the ICardAccount GetBalance method
Public Function GetBalance(AccountNumber as Integer) as Decimal
Implements ICardAccount.GetBalance
' Code to look up balance here

Return balance
End Function

Using Interfaces

When a type supports a specific interface, the caller can directly access the implemented members of the interface from a valid object instance:

Dim SCA as SuperCardAccount = new SuperCardAccount()
MessageBox.Show(SCA.MaxCashAdvance( ) )

We are asking the SCA instance for access to the ICardAccount interface. If you need to be able to tell if a given class implements a certain interface, you can use the TypeOf keyword:

If (TypeOf(SCA) is ICardAccount) then
' rest of code logic here

We can also have either a class or an interface derive from multiple base interfaces as indicated above:

Interface ISuperDuperCardAccount
Inherits ICardAccount, IAccount
End Interface

or, for a class:

Class SuperDuperAccount
Implements ICardAccount
Implements IAccount
' code here
End Class

The .NET base classes make extensive use of interfaces. For example, fire up WINCV and take a look at the socket class:

public IAsyncResult BeginAccept(AsyncCallback callback, object state);
public IAsyncResult BeginConnect(System.Net.EndPoint remoteEP, AsyncCallback callback, object state);
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, AsyncCallback callback, object state);
public IAsyncResult BeginReceiveFrom(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, ref System.Net.EndPoint remoteEP, AsyncCallback callback, object state);
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, AsyncCallback callback, object state);
public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint remoteEP, AsyncCallback callback, object state);
public void Bind(System.Net.EndPoint localEP);

IAsyncResult is one of the interfaces defined in the System base class, and it encapsulates the results of an asynchronous operation on an asynchronous delegate. This is an example of using interfaces to standardize the public methods or properties of multiple classes.

Encapsulating functionality within objects helps us to support future change by creating a separation between the public exposed properties, methods, and events of our classes and the hidden implementation of their members. Provided that the public interface is preserved, the private implementation can safely be changed. This is one of the core concepts of OOP.

Interfaces promote Good OOP programming

This short article only gives an overall glimpse into how interface - based programming can be useful.The main advantage of interface - based programming is the OOP - oriented reusability of predefined behaviors for a method, and the freedom to implement them in custom ways for a particular class. For example, if your class needs to support "For each" iteration, you only need to implement the IEnumerable interface and provide your own method implementation for a GetEnumerator() method. Other valuable pre-built interfaces are IComparable, ICloneable and IDictionary.

Another thing you can do is create and compile your complete interface definitions in assemblies that can then be easily referenced by your new classes, making it easy to extend and formalize the implementations in related classes in your project.

It's easy to see that interface - based programming, whether it involves your own custom interfaces or those provided by the .NET Runtime base classes, has many powerful features and the ability to help standardize and "OOPify" your programming efforts.

Peter Bromberg is an independent consultant specializing in distributed .NET solutions Inc. in Orlando and a co-developer of the developer website. He can be reached at