Interfaces and Polymorphism
In the previous tutorials we created our own custom Collection Class for storing, searching and sorting my collection of Visual Basic Books. We defined the class as having the a number of Methods and Properties. These Methods and Properties define how consumers of that class would interact with the class. These Methods and Properties are what we call the interface to the class. These interfaces are extremely important in Visual Basic, they form a contract by a consumer of the class will interact with that class. As long as that contract is adhered to, the inner workings of a class can change over time without breaking the calling consumer code. These contracts allow us to do some very interesting things with classes which will become apparent in this tutorial on Visual Basic Interfaces and Polymorphism.
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.
The Interface is called IBookCollection as 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 an interface for other classes to implement. It defines the contract on how a consumer of the class, e.g. a 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, rather a series of Property and Method Declarations that a class must implement.
Open the file 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
We have defined this Interface to, not coincidentally, contain all the Public Methods and Properties our VBBookCollection contains. Only the Public methods are of relevance here as the Interface defines how the outside world will interact with the class. Private methods are the inner workings which are hidden from view.
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 interface as the IBookCollection Interface Class we’ve just created. Put your mousepointer 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 methods in that interface and Visual Basic has assisted us here. We “simply” add the implementation code in each empty method stub.
Each Method contains 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 again instructs Visual Basic that our class implements 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 retrospect. It adds the empty stubs at the end of the class. You can either cut and paste the implementation code into the stubs or, as I did, I delete the empty method stubs and add the Implements keyword to the end of each class method call.
For example, the Remove Method in our VBCollectionClass should look like this
Public Sub Remove(ByVal isbn As String) Implements IBookCollection.Remove
Do 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.
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
These is my collection of Non-Fiction Books. Feel free to read them!
Going back to Form1, replace the BookCollection Property from
Public BookCollection As VBBookCollection
to
Public BookCollection As IBookCollection
Meaning 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
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, and obeys that contract of behaviour.
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 has allowed us to maintain these classes without knowing or caring what the class was or did. It just knew 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 as such, the can take a number of forms.
You may be saying “so what” at this point. But think. Say you had an hundreds of classes for managing book collections. We can build maintenance applications 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!