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.