The first is some terminology. In the previous tutorial I mentioned objects, methods, and arguments. That is not exactly correct. Obj-C has receivers, selectors, and messages. Receivers are analogous to objects, selectors to methods, and messages to arguments, but if you're talking with Obj-C programmers it's best to have the terminology right. Also Obj-C does not have constructors. It has allocators and initializers. There is a difference between constructors and initializers. The most visible one being that Obj-C initializers have a return value.
Secondly, Obj-C is a weakly/loosely/dynamically typed language. (I prefer dynamic; it sounds cooler.) This means that all binding is done at runtime. Unlike Java or C++ you can call a selector that doesn't exist for that receiver. The compiler will only generate a warning. However, the code will fail at runtime if the selector does not exist for that receiver. Below is an example of this.
/*
* Pets.m
*
* Graham Watt
*/
#import "Animal.h"
#import "Dog.h"
#import "Cat.h"
#import <stdio.h>
#import <Foundation/NSAutoreleasePool.h>
int main()
{
//why worry about memory management, hence NSAutoreleasePool
NSAutoreleasePool *pool = [ [NSAutoreleasePool alloc] init];
Animal *dog = [ [Dog alloc] initDogWithName: @"Rufus" andAge: 2];
Animal *cat = [ [Cat alloc] initCatWithName: @"Boris" andAge: 3];
printf ("%s is a %s and is %d years old\n",
[ [dog getName] UTF8String],
[ [dog getType] UTF8String],
[dog getAge] );
/*
* The following line will generate a compiler warning because
* not every animal can bark
*/
printf ("%s says \"%s\"\n", [ [dog getName] UTF8String], [ [dog bark] UTF8String] );
printf ("%s is a %s and is %d years old\n",
[ [cat getName] UTF8String],
[ [cat getType] UTF8String],
[cat getAge] );
printf ("%s says \"%s\"\n", [ [cat getName] UTF8String],
[ [cat meow] UTF8String] );
/*
* Both of the following two lines would cause the program to die
* because cats don't bark and dogs don't meow.
*/
//printf("%s says \"%s\"\n", [ [dog getName] UTF8String], [ [dog meow] UTF8String]);
//printf("%s says \"%s\"\n", [ [cat getName] UTF8String], [ [cat bark] UTF8String]);
return 0;
}
Thirdly, Obj-C sort of doesn't support generics. In Java/C++ you would do something like this:
Vector<String> vec = new Vector<String> ();
You cannot do that in Obj-C. Instead, Obj-C has a type called id that assumes the programmer knows what he/she is doing and will implicitly convert the receiver to the appropriate type based on the context. See:
/*
* Generics.m
*
* Graham Watt
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSAutoreleasePool.h>
#import "Dog.h"
#import "Cat.h"
#import <stdio.h>
int main()
{
NSAutoreleasePool *pool = [ [NSAutoreleasePool alloc] init];
NSMutableArray *array = [ [NSMutableArray alloc] init];
[array addObject: [ [Dog alloc] initDogWithName: @"Rufus" andAge: 2] ];
[array addObject: [ [Cat alloc] initCatWithName: @"Brois" andAge: 3] ];
printf("%s says %s\n",
[ [ [array objectAtIndex: 0] getName] UTF8String],
[ [ [array objectAtIndex: 0] bark] UTF8String] );
printf("%s says %s\n",
[ [ [array objectAtIndex: 1] getName] UTF8String],
[ [ [array objectAtIndex: 1] meow] UTF8String] );
return 0;
}
In the two printf statements I use absolutely no typecast of any kind. The only context the runtime has to determine the receiver type is which selector I use. If I called meow for the first receiver or bark for the second there would still be no compiler warning, but the program would fail.
NOTE: when you use id you don't put an asterisk in the declaration like you would for other classes. id is already a pointer to a class.
I personally think using id is better than using generics. It's more intuitive and I believe that C++ templates are processed at compile time and not at runtime.
In closing, I think that Objective C has much to offer the OOP world but is overlooked because the syntax is quite funny to those from a C++/Java background. Obj-C is more flexible by nature than either Java or C++. It does not require a homogenous class hierarchy like Java does (everything goes back to object class) but unlike C++ it is much easier to inherit from a parent class than define your own "orphaned" class. I find it a nice balance between the two.
I have included as a download all of the code I developed for this tutorial, all the instructions needed for compiling, as well as a pdf file of the tutorial itself.
Tutorial files

Reply




MultiQuote




|