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

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

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

1 void drawShape(id shapes[], int count)
2 {
3     for(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: NSObject
2 @end

  定义了一个Circle类的接口,“:”表示的是继承NSObject父类。以@interface开始,@end结束。
注:在Objective-C中,只要看到@符号,就可以将其看中是C的扩展。

2). 方法的定义

  分为两种,对象方法和静态方法:对象方法定义的时候,最前面用减号静态方法(类方法)定义的时候,最前面用加号

  通俗的讲,类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把它称为创建实例的工厂方法。实例方法,要实例化,必须使用类的实例才可以调用的。

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

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

1 @interface NSString : NSObject
2     +(id)string;
3     +(id)stringWithString:(NSString*)aString;
4     +(id)stringWithWithCString:(const char*)cString
5                         encoding:(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             ... //具体实现的代码2
10     }
11     -(void) draw
12     {
13             ... // 具体实现的代码3
14     }
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) 2014年 julian. All rights reserved.
  7 //  面向对象的基本实例,绘制几个几何图形,修改成Objective-C版本
  8 //-------------------------------------修改版,修改Objective_C-------------------------------
  9
 10 /* 1. enum 枚举类型 */
 11 //定义绘制图形的类型: 圆形,矩形,椭圆形
 12 typedef enum{
 13     kCircle,
 14     kRectangle,
 15     kEgg
 16 } ShapeType;
 17
 18 //定义绘制图形的颜色: 红色,绿色和蓝色
 19 typedef enum{
 20     kRedColor,
 21     kGreenColor,
 22     kBlueColor
 23 } ShapeColor;
 24
 25 /* 2. struct 结构体 */
 26 //定义图形的基本属性
 27 typedef struct{
 28     int x, y, width, height;
 29 } ShapeRect;
 30
 31 //定义整体描述的形状
 32 typedef struct{
 33     ShapeType type;
 34     ShapeColor fillColor;
 35     ShapeRect bounds;
 36 } Shape;
 37
 38 /* 3.定义获取颜色名称的函数 */
 39 NSString *colorName (ShapeColor fillColor)
 40 {
 41     switch(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;
 59     ShapeRect 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 {
 69     fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名
 70 }
 71 -(void) setBounds:(ShapeRect)b
 72 {
 73     bounds = b;
 74 }
 75 -(void) draw
 76 {
 77     NSLog(@"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;
 90     ShapeRect 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 {
100     fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名
101 }
102 -(void) setBounds:(ShapeRect)b
103 {
104     bounds = b;
105 }
106 -(void) draw
107 {
108     NSLog(@"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 @end
116
117 //定义一个椭圆和实现方法
118 @interface Egg : NSObject
119 {
120 @private ShapeColor fillColor;
121     ShapeRect bounds;
122 }
123 -(void) setFillColor : (ShapeColor)fillColor;
124 -(void) setBounds:(ShapeRect) bounds;
125 -(void) draw;
126 @end
127
128 @implementation Egg
129 -(void) setFillColor:(ShapeColor) c
130 {
131     fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名
132 }
133 -(void) setBounds:(ShapeRect)b
134 {
135     bounds = b;
136 }
137 -(void) draw
138 {
139     NSLog(@"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 @end
147
148 void drawShape(id shapes[], int count)
149 {
150     for(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     // 定义三个几何图形的数组
160     id shapes[3];
161     // 定义第一个几何图形为 红色的圆形,
162     ShapeRect rect0 ={0,0,10,30};
163     shapes[0] =[Circle new];
164     [shapes[0] setBounds: rect0];
165     [shapes[0] setFillColor: kRedColor];
166
167     // 定义第二个几何图形为 绿色的矩形,
168     ShapeRect rect1 ={30,40,50,60};
169     shapes[1] =[Rectangle new];
170     [shapes[1] setBounds: rect1];
171     [shapes[1] setFillColor: kGreenColor];
172
173     // 定义第三个几何图形为 蓝色的椭圆形,
174     ShapeRect rect2 ={15,18,37,29};
175     shapes[2] = [Egg new];
176     [shapes[2] setBounds: rect2];
177     [shapes[2] setFillColor: kBlueColor];
178
179     drawShape(shapes, 3);
180
181     return 0;
182 }

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

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

后来,通过查询错误信息(参考:http://blog.csdn.net/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中继承方法的使用。

时间: 2025-01-12 23:41:04

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

&lt;&lt;Python基础教程&gt;&gt;学习笔记之|第01章|基础知识

本学习笔记主要用要记录下学习<<Python基础教程>>过程中的一些Key Point,或自己没怎么搞明白的内容,可能有点杂乱,但比较实用,查找起来也方便. 第01章:基础知识 ------ Jython:      Python的Java实现,运行在JVM中,相对稳定,但落后于Python,当前版本2.5,在TA(Python+Robot)会用到 IronPython:  Python的C#实现,运行在Common Language Runtime,速度比Python要快 >

01 3dmax基础教程学习笔记

学习笔记,如有错误请留言,谢谢 01 3dsmax界面介绍 02 界面UI布局 03 查看视点 04 视点显示控制 05 选择方法

jquery基础教程学习笔记一

最近静下心来看书才深刻的体会到:看书真的很重要,只有看书才能让你有心思静下心来思考. 重温<jquery基础教程> 一.事件 主要掌握常见的事件以及理解jquery的事件处理机制. 需要注意的有: 1.事件传播,包括了事件捕获和事件冒泡,以及怎么消除事件传播的影响,以及应用事件传播. 主要的方法有:a.根据事件目标来确定操作,即event.target b.阻止事件传播,即event.stopPapogation c.理解默认事件和jquery事件的区别还有阻止默认事件,即preventDef

linux学习笔记四(shell编程)

前言:最近在学习shell编程,shell编程是一个很强大的编程语言. 目的:方便今后复习. 内容:1.简单的回顾一下编程语言                 1)编程语言:机器语言,汇编语言,高级语言.                 2)编程语言有静态和动态的区分.                             区别:静态语言是一种编译性的语言,要提前知道变量的格式,进过完整的编译之后才能运行,典型的静态语言包括:C.C++.JAVA.C#.                    

python学习笔记day6【面向对象编程】

面向对象编程 一.编程范式:编程的方法论.程序员编程的“套路”及“特点”特点总结,抽象成方法.规范. 二.面向对象编程介绍: 1.描述 世界万物,皆可分类:世间万物,皆为对象:只要是对象,就肯定属于某种品类:只要是对象,就肯定有一定的属性. opp编程(面向对象编程)的抽象机制是将待解问题抽象为面向对象的程序中的对象.利用封装使每个对象都拥有个体的身份.程序便是成堆的对象,彼此通过消息的传递,请求其它对象 进行工作.也可以说opp编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述.

&lt;&lt;Python基础教程&gt;&gt;学习笔记 | 第09章 | 魔法方法、属性和迭代器

这一章,有点抽象,看着有点蛋疼! 双下划线__future__或单下划线有特殊含义,在Python中,这些名字的集合称为魔法方法:最重要的是__init__和一些处理访问对象的方法,这些方法允许你创建自己的序列或者是映射. ------ 准备工作: 将__metaclass__=type放在模块的最开始位置,以确保类时最新式的.考虑下面两个类 class NewStyle(object): more_code_here class OldStyle: more_code_here 如果文件以__

【学习笔记】Python基础教程学习笔记

教程视频网盘共享:http://pan.baidu.com/s/1hrTrR5E 03-python基础.if判断 print 输出数据 print("hahahah")------>hahahah a = 100 print(a)----->直接打印a的值 a = 18 print("我的年龄是%d岁"%a)------>我的年龄是18岁 age = 18 high = 178 print("我的年龄是%d岁,我的身高是%dcm&quo

&lt;&lt;Python基础教程&gt;&gt;学习笔记 | 第13章 | 数据库支持

备注:这章内容相对介绍的比较简单,不过例子比较使用,主要是要掌握如果连接,使用数据库,并以SQLite做示例 ------ Python数据库API 为了解决Python中各种数据库模块间的兼容问题,现在已经通过了一个标准的DB API.目前的API版本(2.0)定义在PEP249中的Python Database API Specification v2.0中. 异常 为了尽可能准确地处理错误,API中定义了一些异常.它们被定义在一种层次结构中,所以可以通过一个except块捕捉多种异常. 连

js基础教程学习笔记

document.write(); document.getElementById(); <script type="text/javascript"></script> 表示在<script></script>之间的文本类型text,javascript是为了告诉浏览器里面的文本是javascript语言 我们可以把js代码与html代码分开,并在html中引用: <script src="script.js"