Objective C for Java Programmers

01 Oct

Objective C was an object-oriented language a long time before Java was invented. It was the preferred programming language for a Steve Jobs operating system, NeXT, before it became the preferred programming language for another Steve Jobs operating system, iOS.

If you’re trying to learn Objective C, you almost certainly want to make iPhone/iPad apps. If this is the case, you should know that, depending on what you want to do, Objective C is not the only language you can use. For example, there exist cross-platform mobile app systems that accept other languages, such as Javascript.

If you’re going with Objective C, and you’re familiar with Java, there’s a few things that you’ll find annoying. I’m sure that this is true if you’re learning Java from Objective C also (for example, if you’re an accomplished iOS programmer and you want to convert your apps to the Android platform). Indeed, Objective C has some nice features that are missing in Java. The problem is, when you’re moving from your comfort zone into new computer-linguistic territory, you don’t instantly fall in love with nice features of the new language. Just ask any C programmer forced to learn Java.

The first annoying thing is that the lack of comprehensive online tutorials. Apple, you might think, would provide these, but they don’t. There’s a bunch of how-tos, but nothing you can print out and read on the plane or in the park. There are, of course, books on the topic. Maybe I should get one.

When you declare a class in Objective C, you get two files, a .h file containing the interface for your class, and a .m file containing the actual code. This should be no surprise – unless you’ve been hiding under a digital rock for your entire programming career, you know about header files. Java doesn’t need these because the compiler does two passes on each .java file, one to figure out the interface, and one to actually compile the class. By “interface” here, I mean the full list of methods and fields, not just any Java interfaces you happen to say you implement. This leads to a kind of quirk of Objective C. To make a method private, you just have to leave it out of the .h file. However, if you do that, any private method in your .m file that you use must be declared before you use it. I don’t think it’s possible to have two private methods calling each other.

You’ll see Objective C code samples where methods are declared with either a + or a – in front. The sooner you learn that “+” means a static method, and “-” means an instance method, the less you will utterly mess up your first attempts to write classes in Objective C. Unfortunately, nobody will tell you.

Speaking of static methods, Objective C doesn’t have “constructors” as a language feature. Instead, you declare a factory method – a static method that returns ¬†your object. However, a static method can’t access the object’s members, so how can a constructor be a static method? The way around this is that

  • every class has a default constructor called “alloc”
  • then, you create an instance method (often called “init”) to be your normal constructor.

If you were coding in Java, then instead of saying

User u = new User(“Joe”, “abc123″);

you’d say

User u = User.alloc().init("Joe","abc123");

In Objective C, this looks like

User* u = [[User alloc] init:@"Joe" withPassword:@"abc123"];

or, if you’d created your static factory method, like this :

User* u = [User withName:@"Joe" andPassword:@"abc123"];

In User.h you’d have this code :

@interface User:NSObject {
   NSString* username;
   NSString* pwd;
-(User*) init:(NSString*)name withPassword:(NSString*)password;
+(User*) withName:(NSString*)name andPassword:(NSString*)password;

and in User.m you’d have :

#import "User.h"
@implementation Car
-(User*) init:(NSString*)name withPassword:(NSString*)password { // the instance-level initialiser
   self = [super init]; // initialises the object of the super class
   if (( self )) { // checks if everything went ok so far
      username = name; // initialise the object's fields
      pwd = password;
   return self; // return the newly constructed object
+(User*) withName:(NSString*)name andPassword:password { // the static factory method
   User * user = [User alloc]; // call the default basic constructor
   [user init:name withPassword:password]; // call the init method
   User * userToReturn = [user autorelease]; // what's this? See my next post.
   return userToReturn; // return the new object
   actually, I could have done all this in one go, via :
   return [[[User alloc] init:name withPassword:password] autorelease];

You’ll see a couple of things there that, for Java programmers, seem a bit quirky. One is the need to declare all objects as type Something* instead of type Something. Type Something is the object itself, in Objective C, whereas type Something* is a reference to that object. In Java, type Something is always a reference to the object. The pure Objective C part of Objective C won’t let you declare anything other than references. However, lurking below the smiling world of Objective C is the deep dark dismal dungeon of C. Allegedly, the Objective C compiler will accept any C code, including all those array bound overflows, memory mismanagement and the bottomless pit of pointer arithmetic.


Tags: , , , , , , , ,

Leave a Reply