900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 《objective-c基础教程》学习笔记(四)—— OC面向对象编程初探

《objective-c基础教程》学习笔记(四)—— OC面向对象编程初探

时间:2023-05-29 13:07:38

相关推荐

《objective-c基础教程》学习笔记(四)—— OC面向对象编程初探

在上篇博文中,我们编写了一个可以输出不同几何类型的小程序。通过C语言的struct结构体,给大家感受了下,对象的大概样子。

如果用Obejctive-C的面向对象的特征来实现。那么,drawShape函数应该修改成这样:

1 void drawShape(id shapes[], int count)2 {3for(int i=0;i<count; i++)4{5 id shape = shapes[i];6 [shape draw];7}8 }

这里,函数上传入的id类型,是指泛型(即:可以用来引用任意类型的对象)。这里的指是一个包含struct结构体的对象。循环体中的id是一个指针类型,指针依次指向数组中的各个几何对象。

[shape draw]:这个写法比较独特,这里的方括号不是像C语言中一样,表示数组。在Objective-C中,方括号表示通知某个对象去做什么操作(类似消息), 括号前第一个参数表示的是:对象,其余部分表示的是需要对象执行的操作

那么,[shape draw] 就可以很好的理解为:向对象shape发送draw的消息。

通过上面改编例子的引入,接下来,就给大家大概的介绍下Objective-C的面向对象的相关内容。在正式转入Objective-C编程之前,先给大家普及下面向对象的几个基本概念。(详细介绍,可以请教度娘或者相关参考书)

(Class):是一种表示对象类型的结构体。对象(Object):是一种包含值,指向其他类的隐藏指针的结构体。实例(Instance):是“对象”的另外一种称呼。消息(Message):是对象可以执行的操作,用于通知对象去做什么。方法(Method):是为响应消息而运行的代码。方法调度(Method Dispatcher):是Objective-C使用的一种机制。接口(Interface):是类为对象提供的特性描述。实现(Implementation):是使接口能正常工作的代码。 好了,接下来我给大家介绍下,在Objective-C中,如何定义类和方法,以及如何使用。 1).类的定义

1 @interface Circle: NSObject2 @end

定义了一个Circle类的接口,“:”表示的是继承NSObject父类。以@interface开始,@end结束。

注:在Objective-C中,只要看到@符号,就可以将其看中是C的扩展。

2).方法的定义

分为两种,对象方法和静态方法:对象方法定义的时候,最前面用减号静态方法(类方法)定义的时候,最前面用加号。 通俗的讲,类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把它称为创建实例的工厂方法。实例方法,要实例化,必须使用类的实例才可以调用的。

1 @interface Circle: NSObject2-(void) setFillColor : (ShapeColor)fillColor;3-(void) setBounds : (ShapeRect) bounds;4-(void) draw;5 @end

调用的时候,要先实例化。Circle v_circle; --> v_circle.setFillColor;那么,什么是静态方法呢?这里给个基本例子:

1 @interface NSString : NSObject2+(id)string;3+(id)stringWithString:(NSString*)aString;4+(id)stringWithWithCString:(const char*)cString5encoding:(NSStringEncoding)enc;6 @end

这个可以直接用类名来调用。--> NSString.string;

PS:上面只是对方法进行了声明,具体的方法还没实现。在定义方法的时候,前一个括号中的表示返回值的类型,后一个表示调用这个方法要传入的参数的类型。

3).方法的实现

一般创建Objective-C项目的时候,会自动创建两个文件。.h结尾的头文件和.m结尾的实现文件(这个.m类似C语言中的.c,C++中的.cpp)。

实现方法就写在.m结尾的实现文件中,方法如下:

1 #import "Shapes.h" 2 @implementation Circle 3-(void) setFillColor :(ShapeColor)fillColor 4{ 5 ... //具体实现的代码1 6} 7-(void) setBounds :(ShapeRect)bounds 8{ 9 ... //具体实现的代码210}11-(void) draw12{13 ... // 具体实现的代码314}15 @end

在Objective-C中,有一种叫中缀符的语法技术。方法的名称和参数可以合在一起。

例如:

[circle setFillColor: kRedColor];

那么,带两个参数的方法如何调用呢?方法如下:

[textThing setStringValue: @"hello there" color: kBlueColor];

好了,那么接下来。我们就将上一篇博文中的代码修改成用Objective-C的语法的吧。

1 // 2 // main.m 3 // ch4_OOP_Shapes_OC 4 // 5 // Created by pcbeta on 14-11-18. 6 // Copyright (c) julian. All rights reserved. 7 // 面向对象的基本实例,绘制几个几何图形,修改成Objective-C版本 8 //-------------------------------------修改版,修改Objective_C------------------------------- 9 10 /* 1. enum 枚举类型 */ 11 //定义绘制图形的类型: 圆形,矩形,椭圆形 12 typedef enum{ 13kCircle, 14kRectangle, 15kEgg 16 } ShapeType; 17 18 //定义绘制图形的颜色: 红色,绿色和蓝色 19 typedef enum{ 20kRedColor, 21kGreenColor, 22kBlueColor 23 } ShapeColor; 24 25 /* 2. struct 结构体 */ 26 //定义图形的基本属性 27 typedef struct{ 28int x, y, width, height; 29 } ShapeRect; 30 31 //定义整体描述的形状 32 typedef struct{ 33ShapeType type; 34ShapeColor fillColor; 35ShapeRect bounds; 36 } Shape; 37 38 /* 3.定义获取颜色名称的函数 */ 39 NSString *colorName (ShapeColor fillColor) 40 { 41switch(fillColor) 42{ 43 case kRedColor: 44 return @"red"; 45 break; 46 case kGreenColor: 47 return @"green"; 48 break; 49 case kBlueColor: 50 return @"blue"; 51 break; 52} 53 } 54 55 //定义一个圆和实现方法 56 @interface Circle : NSObject 57 { 58 @private ShapeColor fillColor; 59ShapeRect bounds; 60 } 61 -(void) setFillColor : (ShapeColor)fillColor; 62 -(void) setBounds:(ShapeRect) bounds; 63 -(void) draw; 64 @end 65 66 @implementation Circle 67 -(void) setFillColor:(ShapeColor) c 68 { 69fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名 70 } 71 -(void) setBounds:(ShapeRect)b 72 { 73bounds = b; 74 } 75 -(void) draw 76 { 77NSLog(@"drawing a circle at (%d %d %d %d) in %@", 78 bounds.x, 79 bounds.y, 80 bounds.height, 81 bounds.width, 82 colorName(fillColor)); 83 } 84 @end 85 86 //定义一个矩形和实现方法 87 @interface Rectangle : NSObject 88 { 89 @private ShapeColor fillColor; 90ShapeRect bounds; 91 } 92 -(void) setFillColor : (ShapeColor)fillColor; 93 -(void) setBounds:(ShapeRect) bounds; 94 -(void) draw; 95 @end 96 97 @implementation Rectangle 98 -(void) setFillColor:(ShapeColor) c 99 {100fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名101 }102 -(void) setBounds:(ShapeRect)b103 {104bounds = b;105 }106 -(void) draw107 {108NSLog(@"drawing a rectangle at (%d %d %d %d) in %@",109 bounds.x,110 bounds.y,111 bounds.height,112 bounds.width,113 colorName(fillColor));114 }115 @end116 117 //定义一个椭圆和实现方法118 @interface Egg : NSObject119 {120 @private ShapeColor fillColor;121ShapeRect bounds;122 }123 -(void) setFillColor : (ShapeColor)fillColor;124 -(void) setBounds:(ShapeRect) bounds;125 -(void) draw;126 @end127 128 @implementation Egg129 -(void) setFillColor:(ShapeColor) c130 {131fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名132 }133 -(void) setBounds:(ShapeRect)b134 {135bounds = b;136 }137 -(void) draw138 {139NSLog(@"drawing a egg at (%d %d %d %d) in %@",140 bounds.x,141 bounds.y,142 bounds.height,143 bounds.width,144 colorName(fillColor));145 }146 @end147 148 void drawShape(id shapes[], int count)149 {150for(int i=0;i<count;i++)151{152 id shape = shapes[i];153 [shape draw];154}155 }156 157 int main(int argc, const char * argv[])158 {159// 定义三个几何图形的数组160id shapes[3];161// 定义第一个几何图形为 红色的圆形,162ShapeRect rect0 ={0,0,10,30};163shapes[0] =[Circle new];164[shapes[0] setBounds: rect0];165[shapes[0] setFillColor: kRedColor];166167// 定义第二个几何图形为 绿色的矩形,168ShapeRect rect1 ={30,40,50,60};169shapes[1] =[Rectangle new];170[shapes[1] setBounds: rect1];171[shapes[1] setFillColor: kGreenColor];172173// 定义第三个几何图形为 蓝色的椭圆形,174ShapeRect rect2 ={15,18,37,29};175shapes[2] = [Egg new];176[shapes[2] setBounds: rect2];177[shapes[2] setFillColor: kBlueColor];178179drawShape(shapes, 3);180181return 0;182 }

View Code

在运行上面代码的时候,我发现一个书本上没有提及的问题。那就是如图:

有两个错误提示,之前以为是代码写的错误。但是反复查阅,还是没有发现问题。

后来,通过查询错误信息(参考:/wbw1985/article/details/7644815)。

找出了错误原因:由于 XCode5.1 中缺省ARC(内存管理的一种模式,后面讲内存管理的时候会详细介绍)就是 ON 的状态,所以编译旧代码的时候往往有"Automatic Reference Counting Issue"的错误信息。

解决的方法是:将项目编译设置中的“Objectice-C Auto Reference Counteting”设为NO。如下所示:

设置完之后点击保存,错误提示就消失了。这个时候点击运行按钮,就可以看到运行结果如图:

但是,通过今天修改过的Objective-C的例子,我们可以看出代码中了有很多地方都是重复的。

比如定义和实现Circle,Rectangle,Egg的代码,基本都是重复的,这就很很大的优化空间了。

下篇博文,我们将继续延续这个例子展开。介绍下Objective-C中继承方法的使用。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。