[.NET fundamentals] Classes vs. Interfaces

July 4, 2012

This is the second instalment in a collection of articles about .NET fundamentals. The first one dealt with Reference and Value types, or “classes” and “structures” as they are known in VB. In this article I’ll discuss the difference between classes and interfaces. But first allow me to bloviate about OOP.

Object Oriented Programming (OOP) is a programming paradigm that has proven very successful indeed. The bulk of programming languages you’ve heard about will  be based on or at least support OOP; LISP, C++, Pascal, Python, the entire .NET framework, the list goes on. I won’t dive into a full description of what OOP is and how it works, there’s plenty of online resources for that already. I’ll just give you a basic breakdown of the concepts.

An ‘Object’ is a collection of data and functions (though technically neither is required) that ‘make sense’ as a unit. Imagine for example a 3D Vector. This vector is defined by three numbers and each of those numbers has a specific meaning. Therefore it makes sense to put them all inside a single class. By naming them x, y and z, it also becomes completely obvious what each number means. The code for this class might look like this:

Class Vector
→→Public X As Double
→→Public Y As Double
→→Public Z As Double
End Class

(it is actually a bad idea to create classes with public fields, but this is not a post about best coding practices).

Furthermore we can add functions to this class that perform standard actions. If you want to know the length of a vector then there’s basically three different situations you may find yourself in.

  1. There is no function anywhere that computes the length of a vector, you have to do the maths yourself every single time from scratch.
  2. There is a global function somewhere that takes a vector and returns the length of said vector.
  3. There is a member function on the vector class that returns the length.

The first option is obviously a bad one. Not only does it slow down development by adding menial tasks, you’ll also have chunks of very similar code sprinkled throughout your code. Option two is a lot better as it eliminates the need to duplicate code, but these global functions are often difficult to find. The third option is the best one in my opinion. Here’s how the code would look for all three cases:

  1. Dim length As Double = Math.Sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z))
  2. Dim length As Double = XXXX.VectorLength(v)
  3. Dim length As Double = v.Length

The vector class with the added Length method might look something like this:

Class Vector
→→Public X As Double
→→Public Y As Double
→→Public Z As Double

→→Public Function Length() As Double
→→→→Return Math.Sqrt((X * X) + (Y * Y) + (Z * Z))
→→End Function
End Class

Everyone who now gets an instance of the Vector class has instant access to the Length() function. Some classes have but a few fields and methods, others may have hundreds.

One of the more useful characteristics of OOP is a mechanism called inheritance. It is possible to extend a class by creating a new class which inherits (or ‘derives’) from another class. This new class gets all the existing functionality for free but, more importantly, it remains of the same kind as the original class. Let’s say that we’re programming something to do with vector field display. We therefore need to draw a lot of vectors on the screen and each vector has a unique colour. We can of course maintain two separate lists, one filled with vectors, the other with colours, but it is often difficult to make sure these lists remain synchronised. A second option is to create an entirely new class which contains both a vector and a colour:

Class VectorPlusColour
→→Public V As Vector
→→Public C As Color
End Class

Inheritance however allows us to create a new class that derives from Vector but adds colour data:

Class VectorPlusColour
→→Inherits Vector
→→Public C As Color
End Class

The beauty of this approach is that VectorPlusColour is a Vector, and therefore every algorithm that works with the type Vector can also work with VectorPlusColour. It is not uncommon for classes to have several levels of inheritance, where each level expands upon the functionality provided by the base class.

In .NET, it is only possible for a class to derive from a single base class. Some languages, most notably C++, support multiple inheritance, but that introduces a large amount of complexity and ambiguity and it doesn’t seem to be a pre-requisite for a successful language as .NET clearly proves.

Whereas a class defines a base set of functionality and data, an interface is something subtly different. The best way to think of an interface in my opinion is to treat it as an agreement or contract. When a class implements an interface, it promises to provide certain functionality. Nothing is mentioned about how this functionality is to be implemented, just that it must be implemented. In other words, when you choose to implement an interface, you have to do all the coding right there and then. The interface itself does not provide skeleton functionality, like a base class would.

A very simple example of this would be the IComparable interface that is part of the core .NET framework. Every class that implements IComparable must contain a function that looks like this:

Public Function CompareTo(ByVal obj As Object) As Integer
End Function

This function compares the current class with some other object and returns a value indicating whether it is equal to, smaller than or larger than some other object. Some operations require that your classes implement certain interfaces. Sometimes the behaviour changes depending on whether you’ve implemented specific interfaces.

Note that you can not tell from an interface what sort of object you’re dealing with. Any class might implement any interface. So let’s say you write a function which uses the IComparable interface to test two objects for equality:

Function AreObjectsEqual(ByVal obj1 As IComparable, ByVal obj2 As Object) As Boolean
→→If (obj1 Is Nothing) Then
→→→→If (obj2 Is Nothing) Then
→→→→→→Return True
→→→→→→Return False
→→→→End If
→→End If
→→Return obj1.CompareTo(obj2) = 0
End Function

The only requirement this function places on the obj1 argument is that it implements the IComparable interface. It doesn’t matter whether obj1 is a Curve or a Surface or a Number or a DataBase or a WebDomain or an Xml Formatter, as long as it implements IComparable we’re good to go.

An interface which is used a lot in RhinoCommon methods is IEnumerable(Of T). IEnumerable is a promise that whoever implements it can behave like a collection of instances. The (Of T) part means the interface is generic, and that the T is not yet completely defined. It has to be replaced with an actual type when it is used in a function. For example, IEnumerable(Of T) can become IEnumerable(Of Point3d), or IEnumerable(Of Curve), or IEnumerable(Of IComparable). There are a lot of different types in .NET that behave like collections. Array, List, Collection, ReadOnlyCollection, SortedList and Dictionary to name just a few. It would be very annoying if a function demanded a specific type of collection. You’d have to convert your actual collection into a different kind of collection just to be able to use that function. The alternative is that we write a unique function for every common type of collection. This is called overloading and it translated into a lot of work for the developer, because now instead of one function she has to write 20. This is why interfaces are so bloody useful. Every collection-like type worth its salt will implement IEnumerable(Of T), making life easier for both the core developer and the user.

One Response to “[.NET fundamentals] Classes vs. Interfaces”

  1. Wendong Wang Says:

    I like the way you describe these concepts. It makes a lot easier for me to understand when you make analogies. Also it is particularly useful that you relate these concepts in .NET back to what’s in RhinoCommon.
    Question 1:
    In your first installment, you were talking about value-type and reference-type in terms of the difference in how they stored in RAM. And you said structures are value-type and classes are reference-type. In this second installment, you explain that in addition to data, functions can be added to classes (or objects?)
    Is class is subset of objects?

    Question 2:
    From your examples, it seems to me that an interface is a method, and also a function inside a class is a method too. You haven’t explicitly explained what a method is. So what is a method?

    Question 3:
    When is the next installment?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: