Interfaces and Polymorphism

In the previous tutorials we created our own custom Collection Class for storing, searching and sorting a Collection Class storing a library of Visual Basic Books.  We defined the Class as having a number of Methods and Properties and these Methods and Properties define how consumers would interact with the Class.  These Methods and Properties define the interface to the Class.  These Interfaces are extremely important in Visual Basic.  As long as that Interface is adhered to, the inner workings of a Class can change over time without changing the calling code.  These Interfaces allow us to do some very interesting things with classes which will become apparent in this tutorial on Visual Basic Interfaces and Polymorphism.

In the previous set of tutorials we have a Presentation Layer (a Form) interacting with the Collection Management Layer (the VBBookCollectionClass)..   If I create another Class containing e.g. my non-Fiction books, the Form would be unable to work with that Class without rework to the code.  The Form is tightly bound to one Class.  By implementing Interfaces, the Form will be able to work with any Class that shared the same Interface as the VBBookCollection Class.   This may sound quite complex but Interfaces are actually extremely straightforward to implement in your code.

To see what I mean, open the Collection Class Project you’ve been working on in the previous tutorials.  Add a New Item to your Visual Basic Project, an Interface called IBookCollection as shown below.

new interface

The Interface is called IBookCollection because it’s a common convention in Visual Basic .NET Development to prefix the name of an Interface with the letter I.  This lets all developers know that the code within the Class is an Interface and not a regular Class.  The purpose of an Interface Class is to provide a common set of Properties and Methods for other classes to implement.  It defines the contract on how a consumer of the Class, in our case the Form, will interact with the Class.  An Interface does not define the inner workings of the Class, there is no code as such in an Interface, but rather a series of Property and Method Declarations that a Class must implement.

Open the newly added Interface Class and the code should look as follows:


Public Interface IBookCollection

End Interface

Paste in the following code so the Interface looks like

Public Interface IBookCollection
     Sub Add(ByVal item As String, ByVal isbn As String)
     Sub Remove(ByVal isbn As String)
     Function Contains(ByVal isbn As String) As Boolean
     Function Count() As Integer
     Function Item(ByVal isbn As String) As String
     Function Item(ByVal index As Integer) As String
     Function Key(ByVal index As Integer) As String
End Interface

This Interface defines all the Public Methods and Properties in our VBBookCollection Class.  Only the Public Methods/Properties are of interest in an Interface as the Interface defines how the outside world will interact with the Class.  Private Methods and variables are part of the inner workings of the class, completely hidden from view of any external consumer.

Add another Class to the Visual Basic Project called NonFictionBookCollection.

Open this Class and add the following code:

Public Class NonFictionBookCollection
     Implements IBookCollection
End Class

This tells Visual Basic that this Class will have the same public Methods and Properties as the IBookCollection Interface Class we’ve just created.  Put your mouse pointer at the end of the word IBookCollection.  Press the enter key.   You should see Visual Basic create empty Method stubs for every Method in that interface.  To implement an Interface, a Class must contain all the Public Methods and Properties in that interface without exception, and Visual Basic has assisted us here.  We “simply” add the implementation code in each empty Method stub.

If you look closely, each Method contains the Implements keyword e.g.

Public Sub Add(ByVal key As String, ByVal value As String) Implements IBookCollection.Add

This tells Visual Basic what Interface method the class method corresponds to.  We could theoretically call the class method something completely different although this isn’t convention.

Now, in our VBBookCollection class add the following line as your first line of code in the class.

Implements IBookCollection

This instructs Visual Basic that our VBBookCollection Class will also implement the IBookCollection Interface.  Press the enter key.  Scroll down the code and Visual Basic has attempted to help us again.  Unfortunately Visual Basic will attempt to implement this Interface but doesn’t do such a good job of it in an existing Class.  It adds empty Method stubs at the end of the Class, even though the Methods already exist.  You can either cut/paste the implementation code into each Method stub or, as I did, delete the empty Method stubs and add the Implements keyword to the end of each existing Method call.

For example, the Remove Method in our VBCollectionClass should look like this:

Public Sub Remove(ByVal isbn As String) Implements IBookCollection.Remove

Repeat this for all the Public Methods in this Class.

We’re now going to populate the NonFictionBookCollection with our code.  Delete all the code in that Class so you are left with:

Public Class NonFictionBookCollection

End Class

Copy and paste all the code from the VBBookCollection Class into the NonFictionBookCollection Class.

The first three lines of code should look as follows:

Public Class NonFictionBookCollection
     Implements IBookCollection
     Private colBookNames = New Collection
     Private colISBN = New Collection

Open the Form and in the Load Event cut the following code:

AddItem("Microsoft Visual Basic 2010 Step By Step", "0735626693")
AddItem("Sams Teach Yourself Visual Basic 2012 in 24 Hours, Complete Starter Kit", "0672336294")
AddItem("Distributed Applications with Microsoft Visual Basic 6.0 McSd Training Kit : For Exam 70-175", "0735608334")
AddItem("Microsoft® ASP.NET Programming with Microsoft Visual Basic® .NET Version 2003 Step By Step", "0735619344")
AddItem("Visual Basic 6 Design Patterns", "0201702657")
AddItem("Excel VBA Programming For Dummies", "0470503696 ")
AddItem("Learn to Program with Visual Basic", "1902745000")
AddItem("Visual Basic 6 Complete", "0782124690")

Paste the code into the VBBookCollection New Event.

New Method

This Event fires when a new instance of that class is created and should look as follows:

Public Sub New()
     AddItem("Microsoft Visual Basic 2010 Step By Step", "0735626693")
     AddItem("Sams Teach Yourself Visual Basic 2012 in 24 Hours, Complete Starter Kit", "0672336294")
     AddItem("Distributed Applications with Microsoft Visual Basic 6.0 McSd Training Kit : For Exam 70-175", "0735608334")
     AddItem("Microsoft® ASP.NET Programming with Microsoft Visual Basic® .NET Version 2003 Step By Step", "0735619344")
     AddItem("Visual Basic 6 Design Patterns", "0201702657")
     AddItem("Excel VBA Programming For Dummies", "0470503696 ")
     AddItem("Learn to Program with Visual Basic", "1902745000")
     AddItem("Visual Basic 6 Complete", "0782124690")
End Sub

In our NonFictionBookCollection add the following code:

Public Sub New()
     AddItem("The 4 Hour Workweek", "0091929113")
     AddItem("The Lean Startup", "0670921602")
     AddItem("Purple Cow: Transform Your Business by Being Remarkable", "014101640X")
     AddItem("Rework", "0091929784")
     AddItem("Code Complete", "0735619670")
     AddItem("Pragmatic Programmer", "020161622X")
     AddItem("Leaving Microsoft to Change the World", "006112107X")
End Sub

This is my Collection of Non-Fiction Books.  Feel free to read them!

Going back to Form1, change the BookCollection Property from:

Public BookCollection As VBBookCollection

To:

Public BookCollection As IBookCollection

The BookCollection Property is now of type IBookCollection.  Any Class that implements this Interface can be assigned to this Property!

In your Sub Main paste the following code:

Module Main
     Sub Main()
          Dim col As New NonFictionBookCollection
          Dim myForm As New Form1
          Form1.BookCollection = col
          Form1.ShowDialog()
     End Sub
End Module

Run your application and the Form allows you to maintain the NonFictionBookCollection.  Change one line of code from:

Dim col As New NonFictionBookCollection

to

Dim col As New VBBookCollection

Run your Project and you’re now maintaining the VBBookCollection Class with the same Form.  The same Form is maintaining two different Classes!  How cool is that?

What is happening here is pretty fundamental.  Form 1 is completely unaware of the type of Class that is being passed to it.  It just knows it implements the IBookCollection Interface, meaning the Form knows what Properties and Methods the Class has.

Public BookCollection As IBookCollection

It doesn’t care what kind of Class it is, or what code is has behind the scenes.  As long as it implements the Interface it will work.  We have abstracted the Public Interface of the Class from the inner workings – the implementation.  The two implementation classes could have got their data from completely different sources e.g. a spreadsheet or database, and our Form wouldn’t care, as long as it had a certain Interface.

This is extremely efficient programming and is called Polymorphism.  A typically long winded word which essentially means that the implementation is separate from the Interface and the implementation can take a number of forms.

You may be saying “so what” at this point.  But think.  Say you had a hundreds of classes for managing book Collections.  We can build maintenance application to iterate through, add, view, update and delete these multiple classes all via one Form.  Without Interfaces and Polymorphism I would have had to create hundreds of separate forms for this – one for each Class.  With Polymorphism I create only one.

Maybe it’s simpler to envisage diagrammatically.  The architecture of this application is as follows:

We have a Presentation Layer in the Form.  This Presentation Layer can present and manipulate information from any Class that implements the Book Collection Interface.  We can have a number of classes that implement this Interface, regardless of the inner workings of those Classes.

These are pretty advanced topics at this stage but stick with me, things will only get more and more clear the more you practise these concepts and put them to real world use.  You are well on the road to becoming an extremely proficient Visual Basic programmer.

Well done!