This tutorial is written assuming you are already familiar with Object Oriented Programming either from C++ or Java.
So, I am not going to dive into the details of OO.
The basic structure of code using inheritance is this:
@interface ChildClass: ParentClass ... @end
It may be obvious to those who have been writing C++/Java, just to get used to the Objective-C code, I will list a very simple code using the inheritance.
In this code, Rectangle is the ChildClass and NSObject is the ParentClass.
@Interface: <Rectangle.h>
#import <Foundation/Foundation.h> @interface Rectangle: NSObject { int width; int height; } @property int width, height; -(void) setWidth: (int) w andHeight: (int) h; -(int) area; @end
@Implementation: <Rectangle.m>
#import "Rectangle.h" @implementation Rectangle @synthesize width, height; //method taking 2 args -(void) setWidth: (int) w andHeight: (int) h { width = w; height = h; } -(int) area { return width*height; } @end
The main program: <main.m>
#import "Rectangle.h" #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Rectangle *rect =[[Rectangle alloc] init]; //set the values [rect setWidth: 10 andHeight: 5]; // print it NSLog(@"rectnagle: w = %i and h = %i", rect.width, rect.height); NSLog(@"rectnagle: area = %i",[rect area]); // free memory [rect release]; [pool drain]; return 0; }
The output is:
rectangle: w = 10 and h = 5 rectangle: area = 50
Suppose we need a Square class and we want to use the method "area" of Rectangle class instead of making a new "area" method.
Here is the code for a Square class as a subclass of Rectangle.
Square Interface: <Square.h>
#import "Rectangle.h" @interface Square: Rectangle -(void) setSide: (int) s; -(int) side; @end
Square Implementation: <Square.m>
#import "Square.h" @implementation Square: Rectangle -(void) setSide: (int) s { [self setWidth: s andHeight: s]; } -(int) side { return width; } @end
Our main program can be changed like this:
#import "Square.h" #import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //Rectangle *rect =[[Rectangle alloc] init]; Square *square =[[Square alloc] init]; //set the values [square setSide: 10]; // print it NSLog(@"Square: side = %i",[square side]); NSLog(@"Square: area = %i",[square area]); // free memory [square release]; [pool drain]; return 0; }
Though we added two new methods, "setSide:" and "side", to the Square class,
we did not add an "area" method
since we are inheriting it from the Rectangle class.
The output is:
Square: side = 10 Square: area = 100
Our Rectangle class in the code above does not have much information.
It gives us only the size of the rectangle. Not the location.
So, let's add a new class PointXY to our Rectancle class which has data members x and y.
Here is our new Rectangle Interface.
@Interface file: <Rectangle.h>
#import <Foundation/Foundation.h> @class PointXY; @interface Rectangle: NSObject { int width; int height; PointXY *Origin; } @property int width, height; -(PointXY *) Origin; -(void) setOrigin: (PointXY *) pt; -(void) setWidth: (int) w andHeight: (int) h; -(int) area; @end
Here, the new line "@class PointXY" let the compiler know what a "PointXY" is
when it sees it as one of the instance variables in the Rectangle class.
We call "@class className" as forward declaration.
Our new Rectangle Implementation.
@Implementation file: <Rectangle.m>
#import "Rectangle.h" @implementation Rectangle @synthesize width, height; -(void) setWidth: (int) w andHeight: (int) h { width = w; height = h; } -(int) area { return width*height; } -(void) setOrigin: (PointXY *) pt { Origin = pt; } -(PointXY *) Origin { return Origin; } @end
Note that we added two method to the implementation of Rectangle:
"setOrigin:" and "Origin".
But we have not defined our PointXY class yet.
Here is the interface for PointXY class
@Interface file: <PointXY.h>
#import <Foundation/Foundation.h> @interface PointXY: NSObject { int x; int y; } @property int x, y; -(void) setX: (int) xCoord andY: (int) yCoord; @end
Implementation for PointXY class
@Implementation file: <PointXY.m>
#import "PointXY.h" @implementation PointXY @synthesize x,y; -(void) setX: (int) xCoord andY: (int) yCoord { x = xCoord; y = yCoord; } @end
So far, we defined 4 files:
"PointXY.m", "PointXY.h", "Rectangle.m", and "Rectangle.h".
Now, it's time to test it.
Here is our last code for the testing: <rectOrigin.m>
#import "Rectangle.h" #import "PointXY.h" int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Rectangle *rect =[[Rectangle alloc] init]; PointXY *point =[[PointXY alloc] init]; //set the values [point setX: 100 andY: 300]; [rect setWidth: 200 andHeight: 100]; rect.Origin = point; // print it NSLog(@"Rectangle: w = %i, h = %i", rect.width, rect.height); NSLog(@"Recangle: Origin = (%i,%i)", rect.Origin.x, rect.Origin.y); // free memory [rect release]; [point release]; [pool drain]; return 0; }
The output is:
Rectangle: w = 200, h = 100 Rectangle: area = 20000 Rectangle: Origin = (100,300)