上一篇展示了如何用传统的“面向过程编程方法”,实现画“矩形”、“圆”、“椭圆”,这一篇看下如何改用OOP的方法来实现:
因为要用到“颜色”以及“矩形区域”二个枚举,先把他们抽出来单独放在CommDef.h文件中
//定义“几何形状颜色”枚举 typedef enum { kRedColor, kGreenColor, kBlueColor } ShapeColor; //定义“几何形状矩形区域”结构 typedef struct { int x,y,width,height; } ShapeRect;
然后再定义基类Shape,注意:在obj-C中,定义一个类通常分成二部分,一部分是".h"的文件,用来申明类有哪些成员(也称为类的定义文件,类似于接口),另一部分是".m"的文件,用来提供具体实现
Shape类的申明部分如下:(Shape.h)
// // Shape.h // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "CommDef.h" @interface Shape : NSObject { ShapeColor fillColor; ShapeRect bounds; } - (void) setFillColor:(ShapeColor) fillColor; - (void) setBounds:(ShapeRect) bounds; - (void) draw; - (NSString*) getColorName:(ShapeColor) fillColor; @end //Shape
Shape类的实现部分如下:(Shape.m)
// // Shape.m // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Shape.h" @implementation Shape - (void) setBounds:(ShapeRect)b { bounds = b; } - (void) setFillColor:(ShapeColor)f { fillColor =f; } //注:这个方法留给子类去实现,所以这里只要一个空壳就行了 - (void) draw { } - (NSString*) getColorName:(ShapeColor)f { switch (f) { case kRedColor: return @"red"; break; case kGreenColor: return @"green"; break; case kBlueColor: return @"blue"; break; default: return @"no clue"; break; } } @end
语法有点奇怪,初次接触,只能强迫自己忘记吧。
然后定义子类Circle
申明部分Circle.h
// // Circle.h // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Shape.h" //注:因为Circle类不需要扩展其它方法,所以这里也只要一个空壳 @interface Circle : Shape { } @end
实现部分Circle.m
// // Circle.m // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Circle.h" @implementation Circle -(void) draw { NSLog(@"drawing a Cirle at (%d,%d,%d,%d) in %@",bounds.x,bounds.y,bounds.width,bounds.height,[super getColorName:fillColor]); } @end
注:上面展示了在obj-C中如何调用父类的方法[super getColorName:fillColor]
子类Rectangle
// // Rectangle.h // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Shape.h" @interface Rectangle : Shape { } @end
实现部分
// // Rectangle.m // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Rectangle.h" @implementation Rectangle -(void) draw { NSLog(@"drawing a Rectangle at (%d,%d,%d,%d) in %@",bounds.x,bounds.y,bounds.width,bounds.height,[super getColorName:fillColor]); } @end
子类Ellipse
// // Ellipse.h // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Shape.h" @interface Ellipse : Shape{ } @end
实现部分
// // Ellipse.m // HelloWorld // // Created by jimmy.yang on 11-1-26. // Copyright 2011 __MyCompanyName__. All rights reserved. // #import "Ellipse.h" @implementation Ellipse -(void) draw { NSLog(@"drawing a ellipse at (%d,%d,%d,%d) in %@",bounds.x,bounds.y,bounds.width,bounds.height,[super getColorName:fillColor]); } @end
最后看下调用的主函数HelloWorld.m
#import "CommDef.h" #import "Circle.h" #import "Rectangle.h" #import "Ellipse.h" int main (int argc, const char * argv[]) { id shape[2] ; ShapeRect rect0 = {0,0,10,30}; shape[0] = [Circle new]; [shape[0] setBounds:rect0]; [shape[0] setFillColor:kGreenColor]; [shape[0] draw]; ShapeRect rect1 = {0,0,40,50}; shape[1] = [Rectangle new]; [shape[1] setBounds:rect1]; [shape[1] setFillColor:kRedColor]; [shape[1] draw]; ShapeRect rect2 = {0,0,30,30}; shape[2] = [Ellipse new]; [shape[2] setBounds:rect2]; [shape[2] setFillColor:kBlueColor]; [shape[2] draw]; return 0; }
注:上面的代码中有一个id的变量,在obj-C中id相当于“任意类型”,意为指向某对象的指针(哪怕你不知道这个对象是什么类型),总之,如果你不知道某对象的具体类型时,用它就对了。同时我们也看到了,创建一个类的实例用“[类 new]”来完成。
最后附上文件结构图: