Sunday, August 27, 2006

Object-Oriented Overview and Shared vs Instance Methods

In order to be a quality software developer today, you need to have an understanding of object oriented programming. However, if you want to be an Agile or Test Driven developer, you need a much stronger understanding. Why? Because when you're agile, you must be able to make changes quickly without affecting the system. In order to do that, you need to reduce (or eliminate) duplicate code and minimize coupling. OOP provides ways to do these things better than (in my opinion) procedural programming.
The purpose of this post is to provide a quick start to OOP. I hope you find it helpful.
Object-Oriented Overview
I found a simple and short tutorial to OOP concepts. It's in Java, but the concepts work for any OO language and it's short and simple.
So do you know the difference between a class (or Type) and an object?
A Class is the code that defines an object. An object is an instance of that class. If you "new up" a class, you get an object. It's that simple!
Shared/static vs. Instance Methods
Now that you understand the differences between a class and an object we can discuss the difference between Shared and Instance methods. Shared methods are at the class level, instance methods are on the object..err...instance. This means that each object that is created has it's own copy of the instance methods, but the shared function is used by all code in the application. I guess that is why the VB.NET team named them "shared".  Since shared methods are global, they can be helpful in some situations, for example, factory methods or singletons, but in general I avoid them for a few reasons:
You can't put shared methods on interfaces
Shared methods can cause multi-threading problems
They encourage procedural coding
For this example we'll use the good ol' Person Class.
        Public Class Person
    Public Sub New(ByVal firstName As String, ByVal lastName As String)
        Me.FirstName = firstName
        Me.LastName = lastName
    End Sub
    Public FirstName As String
    Public LastName As String
    'Instance Method
    Public Function DisplayName() As String
        Return String.Format("{0}, {1}", Me.LastName, Me.FirstName)
    End Function
    'Shared Functions
    Public Shared Function Steve() As Person
        Return New Person("Steve", "Person")
    End Function
    Public Shared Function Tim() As Person
        Return New Person("Tim", "Person")
    End Function
End Class
In the Person class, FirstName and LastName fields are data stored within an object, and the DisplayName function describes a behavior for the class.
An object is an instance of a class. When "new up" a class we create a new instance (object) of the class. In this example, myPerson is an object, Person is a Class.

    Private myPerson As Person = New Person
To access a shared method, you don't need to "new up" an object. You can call it directly on the class. For example, Person.Steve() or Person.Tim(), work without "newing up" an object.
However, we don't have access to instance (non-shared) methods. You can't call Person.DisplayName(), but you can "new up" a person object and call DisplayName(), New Person().DisplayName.
In order to add to the confusion, VB.NET shows Shared methods on object variables. Calling myPerson.Steve() on an object instance works fine in VB.NET, but causes confusion. Please don't do this. I was hoping the VB.NET team would remove this "feature" in 2005, but it would have broken alot of systems.
I hope this wasn't too confusing, but understanding the basic concepts will help you develop better quality systems.



  1. Hi Tim,

    Liked your article a lot. I know that its been a while since you posted this article but here goes...

    I have been seriously confused about whether to use shared functions or functions called using instantiated objects. I have seen some vague descriptions with even more vague examples. As far as i am concerned I think that shared functions can do everything that instantiated object functions can do(even instances of control objects can be passed to them for them to work on). So in this case what would be the point of creating objects and using them? I am a novice. Please help me understand this :(

  2. Shared functions can't access non-shared/instance fields.

    You'll need to create an instance of an object if you want to encapsulate data.

    For example each of these variables have their own data:
    x = new Person("x", "x");
    y = new Person("y", "y");
    x.DisplayName() "x,x"
    y.DisplayName() "y,y"

    If we stored FirstName and LastName in a Shared field we would get:
    x = new Person("x", "x");
    y = new Person("y", "y");

    x.DisplayName() == "y,y"
    y.DisplayName() == "y,y"

    If you only used shared methods and fields, you only get 1 set of data within the AppDomain...thus you could only have 1 person.