Monthly Archives: March 2009

Why my brain hurts – Objective C vs VB.Net

Standard

It has been said that software developers can expand their skills by learning a new computer language a year.  The similarity of languages I have encountered up to this point led me to doubt whether this was so.  I was wrong.

In my quest to create the ultimate iPhone application, I’ve had to learn not only a new platform but a whole new computer language, “Objective C”.  My “native” computer language is C, so imagine my consternation when found how different Objective C appears from C Sharp and C++.

So far there doesn’t seem to be any direct comparison between .net languages and Objective C, so I thought I’d post a small article on the subject.  I have decided to use VB.Net as the basis of comparison, but I’m sure C Sharp developers can understand the concepts.   This article is based on the fine Wikipedia introduction to Objective C.  I encourage you to take a look at this.

 

 

Method Invocation and Method Passing

To invoke a method on an Objective C object, we “pass a message”.  This differs from VB.Net in that a method must exist in order to invoke it.

Declaration of classes, by convention are done in two seperate files, a “.h” header file containing an interface declaration and a “.m” (method implementation) containing the actual class code.

HelloWorld.h

@interface HelloWorld : object 

– (id) hello;

@end

 

HelloWorld.m

 

#import “HelloWorld.h”

 

@implementation HelloWorld

– (id) hello

{

   printf(“Hello World”);

}

 

To use this class:

HelloWorld * myhello = [[HelloWorld alloc] init];

[myhello hello];

 

A rough VB.Net equivalent might be:

 

Public Class HelloWorld

   Public Sub Hello

        Console.WriteLn(“Hello World”)

   End Sub

End Class

 

Invoked by:

 

Dim myhello As New HelloWorld

myhello.hello

 

 

A big difference between these examples, is that in the Objective C case, the hello method does NOT have to be implemented at all.  It’s only responding to a “message” that the class may or may not have an implementation for.

 

Admittedly this does produce a compiler warning “warning:’HelloWorld’ may not respond to ‘-hello'”, but it still compiles.

 

A better VB.Net equivalent may be the use of reflection to check for the existence of a method prior to invocation:

 

Dim myhello As New HelloWorld

If myHello.GetType.GetPropInfo(“Hello”) IsNot Nothing Then myHello.hello

 

Another way would be to treat the object as an “object”.  For example:

Dim myhello As New HelloWorld

Ctype(myhello,object).Hello

 

That’s probably missing the point however, because it effectively causes an error at runtime, whereas ObjectiveC does not produce an error.

 

Another possible VB.Net equivalent could be using Events.  Are these equivalent to messages?

 

Public Class HelloWorld

   Private WithEvents moHelloWorldEventSource As HelloWorldEvents 

   Public Sub New(eventSource As HelloWorldEvents)

        moHelloWorldEventSource = eventSource

   End Sub

 

   Private Sub Hello Handles moHelloWorldEventSource.Hello

        Console.WriteLn(“Hello World”)

   End Sub

End Class

Public Class HelloWorldEventSource

      Public Event Hello

      Public Sub Hello

           RaiseEvent Hello

      End Sub

End Class

 

To invoke this masterpiece:

 

Dim helloEvents As New HelloWorldEventSource

Dim myhello As New HelloWorld(helloEvents)

helloEvents.Hello

 

 

Another capability of Objective C is to pass an unhandled method invocation to another object.  VB.Net does not seem to have an equivalent of this.

 

Protocols (Interfaces)

 

Protocols introduce the multiple inheritance of specification, but not implementation through the introduction of “protocols”.

 

Our Objective C hello world class could implement a prototcol:

 

@protocol DescribeDialect

– (void)DescribeYourLanguage;

@end

 

 Like this:

 

@interface HelloWorld : Object <DescribeDialect>

….

@end

 

I get the impression that although HelloWorld declares it implements the DescribeDialect protocol, I’m not sure if it really has to implement each of the methods.  I’m guessing it should.

 

The vb.net equivalent is quite direct:

Public Interface DescribeDialect

    Sub DescribeYourLanguage

End Interface

 

Public Class HelloWorld

     Implements HelloWorld

….

End Class

 

The only element of confusion here is the use of the word “interface” between the languages.  I suppose knowing “protocol” exists helps with this.

 

Dynamic Typing

A programming language is said to be dynamically typed when the majority of it’s type checking is performed at runtime as opposed to compile time.

 

The previously described “optional” implementation of a passed message allows for increased flexibility.  See “Forwarding” for more information.

 

Static typing information may also be added to variables.  The information is then checked at compile time.

 

For example:

 

– setMyValue:(id) foo;

– setMyValue:(id <aProtocol>) foo;

– setMyValue:(NSNumber*)foo;

 

The vb equivalent appears to be declarations with multiple signatures, like this:

 

Public Sub setMyValue(foo As object)

End Sub

Public Sub setMyValue(foo As DescribeDialect)

End Sub

Public Sub setMyValue(foo As String)

End Sub

 

Post Java 1.5 and the .net languages also support “generics”.  I am unsure at this stage if Objective C supports this or not.

 

Forwarding (Delegation)

Since Objective-C permits the sending of a message to an object which might not respond to it, the object has a number of things it can do with the message. One of these things could be to forward the message on to an object which can respond to it. Forwarding can be used to implement certain design patterns, such as the Observer pattern or the Proxy pattern very simply.

There is no direct VB.Net equivalent of this behaviour.  See the wikipedia article for more information.

Categories

In VB.Net 9, a new feature called “Extension Methods” allowed the creation of extra methods on sealed classes.  Objective C’s “categories” are a similar way of creating groupings of methods in separate files that  allow the extension of a base class at runtime.

If we wanted to extend the HelloWorld class above to have an extra Goodbye method, in Objective C we could write:

 

HelloWorldGoodbyes.h

 

#import “HelloWorld.h”

 

@interface HelloWorldDisplay  (HelloWorld) 

– (id) goodbye;

@end

 

HelloWorldGoodbyes.m

 

#import “HelloWorld.h”

 

@implementation HelloWorld

– (id) goodbye

{

   printf(“Bye”);

}

 

The VB.Net equivalent using extension methods could be:

 

Imports System.Runtime.CompilerServices

Module HelloWorldDisplay

 

      <Extension()>Public Sub goodbye(Byval targetHelloWorld As HelloWorld)

               Console.WriteLn(“Bye”)

      End Sub

 

End Module

 

 

A similar VB.Net feature is “partial” classes, although these are compile time constructs.

 

Partial Public Class HelloWorld

   Public Sub Hello

        Console.WriteLn(“Hello World”)

   End Sub

End Class

 

Partial Public Class HelloWorld

   Public Sub Goodbye

        Console.WriteLn(“Bye”)

   End Sub

End Class

 

I don’t believe either of these equivalents support Objective C’s ability to override the base implementation.

 

Posing

Class Posing is an Objective C feature that allows messages sent to the target class to be wholy replaced by calls to a substitute class with the same implementation.

A class may only pose as one of its direct or indirect superclasses

  • The posing class must not define any new instance variables which are absent from the target class (though it may define or override methods).
  • The target class may not have received any messages prior to the posing.

Posing, similarly to categories, allows globally augmenting existing classes. Posing permits two features absent from categories:

  • A posing class can call overridden methods through super, thus incorporating the implementation of the target class.
  • A posing class can override methods defined in categories.

 

Here’s an example:

 

@interface CustomNSApplication : NSApplication

@end

 

@implementation CustomNSApplication

– (void) setMainMenu: (NSMenu*) menu

{

     // do something with menu

}

@end

 

class_poseAs ([CustomNSApplication class], [NSApplication class]);

 

There is no direct VB.Net equivalent of this functionality.  Similar constructs may be created by implementing a singleton pattern combined with an interface.

 

It appears that this feature has been “depreciated” in MacOS 10.5 and onward, so I wont dedicate discuss it any further.

 

#import

 

The #import directive is similar to the #include directive in C, except it only includes a nested file once.   In VB.Net files in the same “project” are automatically included together in this way.

 

If the developer decides to structure their code with namespaces, the VB.Net “Imports” keyword allows inclusion of namespaced classes without having to prefix the namespace path.

And so ends our brief comparison of the two languages.  If you’re after a comparative critique, I am sorry to disappoint you.  Each language has it’s strengths and weaknesses.  At the moment I’m not qualified to comment either way.

If you found this useful, feel free to leave a comment.

 

Links

Advertisements