Tuesday, December 02, 2003

Interface and Abstract Class - Part 1


The next pattern (adapter) uses an Interface and I thought I'd have a go at simply describing what an interface is, what an abstract class is and what the difference between them is. My main reason is for the benefit of programmers who are not familiar with object oriented concepts or who had worked with Visual Basic 6, which has some strange ideas of what Interfaces and Abstract Classes are.

When .NET first came out I took a course in it to get up to speed. I had done a good bit of programming in Java so I was familiar with object oriented programming and was happy to see that the ".NET" changes that had been made to Microsoft's languages were basically a copy of Java. Suddenly VB was a real language and no longer a three-legged mongrel with a missing ear. The guy giving the course was a long term VB programmer and unfortunately it was quite plain from early on that he had a poor understanding of object oriented concepts. He told us that there was no real difference between an Interface and an Abstract Class and when I (big mouth that I am) told him they were different he said, "that may be the case in Java but not in .NET." I think his misunderstanding stemmed from the fact that VB6 didn't have class inheritance but sort of "interface inheritance" so he was stuck with the idea that inheritance had to come from something that had no code in it but just signatures.

What is an Interface?

Simply put, an interface is a sort of class with method signatures but no code. It could be described as a class with no implementation. It can contain method, event and property signatures and any class that implements the interface must implement those members. It's as if the Interface is a legal contract that says what the agreement is on how a class implementing the Interface will present itself to the world. For example if the Interface has a method "Execute()" then the implementing class must have a method with the same signature and must add the code to do whatever "Execute()" is supposed to do.

Because the Interface is just a contract you cannot instantiate an object of that type. Let's say we have an interface like this:


Public Interface InterfaceX
Property Command() As String
Sub Execute()
End Interface

You may think you can do this with it:


Dim myVar As New InterfaceX
myVar.Command = "Select * from Whatever"
myVar.Execute()

Unfortunately it won't work because an Interface is just a contract and you can't instantiate it.

So how can we use the Interface? Let's create a class that implements the Interface:


Public Class ClassX : Implements InterfaceX
Public Property Command() As String Implements InterfaceX.Command
'code goes here
End Property
 
Public Sub Execute() Implements InterfaceX.Execute
'code goes here
End Sub
End Class

Now we can do this:


Dim myVar As InterfaceX
myVar = New ClassX
myVar.Command = "Select * from Whatever"
myVar.Execute()

Well great, you say, but why didn't you just do this:


Dim myVar as New ClassX
myVar.Command = "Select * from Whatever"
myVar.Execute()

If you had one class with an Execute() method then there would be no need for an Interface, but what if you have a situation where you are going to have a collection containing many objects of 10 different classes and all will need to be processed? Are you going to write code like this?


Dim myVar1 as Class1
Dim myVar2 as Class2
'etc ...
Dim myVar10 as Class10
For n = 0 to CollectionX.Length - 1
If Typeof CollectionX(n) is Class1 then
myVar1 = CType(CollectionX(n), Class1)
myVar1.Execute()
ElseIf Typeof CollectionX(n) is Class2 then
myVar2 = CType(CollectionX(n), Class2)
myVar2.ExecuteProc()
'etc ...
ElseIf Typeof CollectionX(n) is Class10 then
myVar10 = CType(CollectionX(n), Class10)
myVar10.ExecuteStatement()
End If
Next

Wouldn't you rather do something like this?


Dim myVar as InterfaceX
For Each myVar in CollectionX
myVar.Execute()
Next

That is the beauty of an Interface.

Tomorrow: Abstract Classes

No comments: