《objective-c基础教程》学习笔记(四)—— OC面向对象编程初探
在上篇博文中,我们编写了一个可以输出不同几何类型的小程序。通过C语言的struct结构体,给大家感受了下,对象的大概样子。
如果用Obejctive-C的面向对象的特征来实现。那么,drawShape函数应该修改成这样:
void drawShape(id shapes[], int count)
{
for(int i=;i<count; i++)
{
id shape = shapes[i];
[shape draw];
}
}
这里,函数上传入的id类型,是指泛型(即:可以用来引用任意类型的对象)。这里的指是一个包含struct结构体的对象。循环体中的id是一个指针类型,指针依次指向数组中的各个几何对象。
[shape draw]:这个写法比较独特,这里的方括号不是像C语言中一样,表示数组。在Objective-C中,方括号表示通知某个对象去做什么操作(类似消息), 括号前第一个参数表示的是:对象,其余部分表示的是需要对象执行的操作。
那么,[shape draw] 就可以很好的理解为:向对象shape发送draw的消息。
通过上面改编例子的引入,接下来,就给大家大概的介绍下Objective-C的面向对象的相关内容。在正式转入Objective-C编程之前,先给大家普及下面向对象的几个基本概念。(详细介绍,可以请教度娘或者相关参考书)
@interface Circle: NSObject
@end
定义了一个Circle类的接口,“:”表示的是继承NSObject父类。以@interface开始,@end结束。
注:在Objective-C中,只要看到@符号,就可以将其看中是C的扩展。
2). 方法的定义
@interface Circle: NSObject
-(void) setFillColor : (ShapeColor)fillColor;
-(void) setBounds : (ShapeRect) bounds;
-(void) draw;
@end
@interface NSString : NSObject
+(id)string;
+(id)stringWithString:(NSString*)aString;
+(id)stringWithWithCString:(const char*)cString
encoding:(NSStringEncoding)enc;
@end
这个可以直接用类名来调用。--> NSString.string;
PS:上面只是对方法进行了声明,具体的方法还没实现。在定义方法的时候,前一个括号中的表示返回值的类型,后一个表示调用这个方法要传入的参数的类型。
3). 方法的实现
一般创建Objective-C项目的时候,会自动创建两个文件。.h结尾的头文件和.m结尾的实现文件(这个.m类似C语言中的.c,C++中的.cpp)。
实现方法就写在.m结尾的实现文件中,方法如下:
#import "Shapes.h"
@implementation Circle
-(void) setFillColor :(ShapeColor)fillColor
{
... //具体实现的代码1
}
-(void) setBounds :(ShapeRect)bounds
{
... //具体实现的代码2
}
-(void) draw
{
... // 具体实现的代码3
}
@end
在Objective-C中,有一种叫中缀符的语法技术。方法的名称和参数可以合在一起。
例如:
[circle setFillColor: kRedColor];
那么,带两个参数的方法如何调用呢?方法如下:
[textThing setStringValue: @"hello there" color: kBlueColor];
好了,那么接下来。我们就将上一篇博文中的代码修改成用Objective-C的语法的吧。
//
// main.m
// ch4_OOP_Shapes_OC
//
// Created by pcbeta on 14-11-18.
// Copyright (c) 2014年 julian. All rights reserved.
// 面向对象的基本实例,绘制几个几何图形,修改成Objective-C版本
//-------------------------------------修改版,修改Objective_C------------------------------- /* 1. enum 枚举类型 */
//定义绘制图形的类型: 圆形,矩形,椭圆形
typedef enum{
kCircle,
kRectangle,
kEgg
} ShapeType; //定义绘制图形的颜色: 红色,绿色和蓝色
typedef enum{
kRedColor,
kGreenColor,
kBlueColor
} ShapeColor; /* 2. struct 结构体 */
//定义图形的基本属性
typedef struct{
int x, y, width, height;
} ShapeRect; //定义整体描述的形状
typedef struct{
ShapeType type;
ShapeColor fillColor;
ShapeRect bounds;
} Shape; /* 3.定义获取颜色名称的函数 */
NSString *colorName (ShapeColor fillColor)
{
switch(fillColor)
{
case kRedColor:
return @"red";
break;
case kGreenColor:
return @"green";
break;
case kBlueColor:
return @"blue";
break;
}
} //定义一个圆和实现方法
@interface Circle : NSObject
{
@private ShapeColor fillColor;
ShapeRect bounds;
}
-(void) setFillColor : (ShapeColor)fillColor;
-(void) setBounds:(ShapeRect) bounds;
-(void) draw;
@end @implementation Circle
-(void) setFillColor:(ShapeColor) c
{
fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名
}
-(void) setBounds:(ShapeRect)b
{
bounds = b;
}
-(void) draw
{
NSLog(@"drawing a circle at (%d %d %d %d) in %@",
bounds.x,
bounds.y,
bounds.height,
bounds.width,
colorName(fillColor));
}
@end //定义一个矩形和实现方法
@interface Rectangle : NSObject
{
@private ShapeColor fillColor;
ShapeRect bounds;
}
-(void) setFillColor : (ShapeColor)fillColor;
-(void) setBounds:(ShapeRect) bounds;
-(void) draw;
@end @implementation Rectangle
-(void) setFillColor:(ShapeColor) c
{
fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名
}
-(void) setBounds:(ShapeRect)b
{
bounds = b;
}
-(void) draw
{
NSLog(@"drawing a rectangle at (%d %d %d %d) in %@",
bounds.x,
bounds.y,
bounds.height,
bounds.width,
colorName(fillColor));
}
@end //定义一个椭圆和实现方法
@interface Egg : NSObject
{
@private ShapeColor fillColor;
ShapeRect bounds;
}
-(void) setFillColor : (ShapeColor)fillColor;
-(void) setBounds:(ShapeRect) bounds;
-(void) draw;
@end @implementation Egg
-(void) setFillColor:(ShapeColor) c
{
fillColor = c; //fillColor为实例变量,为了防止同名,传入的参数要取别名
}
-(void) setBounds:(ShapeRect)b
{
bounds = b;
}
-(void) draw
{
NSLog(@"drawing a egg at (%d %d %d %d) in %@",
bounds.x,
bounds.y,
bounds.height,
bounds.width,
colorName(fillColor));
}
@end void drawShape(id shapes[], int count)
{
for(int i=;i<count;i++)
{
id shape = shapes[i];
[shape draw];
}
} int main(int argc, const char * argv[])
{
// 定义三个几何图形的数组
id shapes[];
// 定义第一个几何图形为 红色的圆形,
ShapeRect rect0 ={,,,};
shapes[] =[Circle new];
[shapes[] setBounds: rect0];
[shapes[] setFillColor: kRedColor]; // 定义第二个几何图形为 绿色的矩形,
ShapeRect rect1 ={,,,};
shapes[] =[Rectangle new];
[shapes[] setBounds: rect1];
[shapes[] setFillColor: kGreenColor]; // 定义第三个几何图形为 蓝色的椭圆形,
ShapeRect rect2 ={,,,};
shapes[] = [Egg new];
[shapes[] setBounds: rect2];
[shapes[] setFillColor: kBlueColor]; drawShape(shapes, ); return ;
}
在运行上面代码的时候,我发现一个书本上没有提及的问题。那就是如图:
有两个错误提示,之前以为是代码写的错误。但是反复查阅,还是没有发现问题。
后来,通过查询错误信息(参考: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中继承方法的使用。
《objective-c基础教程》学习笔记(四)—— OC面向对象编程初探的更多相关文章
- Python学习笔记四:面向对象编程
一:定义类并创建实例 Python中定义类,通过class关键字,类名开头大写,参数列表为所继承的父类.如果没有需要明确继承的类,则继承object. 使用类来创建对象,只需 类名+() 形式即可,p ...
- PythonI/O进阶学习笔记_3.1面向对象编程_python的多态和鸭子类型
前言: 与第一篇的面向对象内容不同的是,第一篇中的面向对象更多的是与类.对象结合起来的概念粗浅理解,就是在编程历史中诞生的一种思想方法. 这篇的面向对象编程,更多落实到在语言设计实现中,是如何体现面向 ...
- PythonI/O进阶学习笔记_3.2面向对象编程_python的封装
前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第三篇 封装. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...
- PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)
前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...
- Python基础教程学习笔记:第一章 基础知识
Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...
- python学习笔记15(面向对象编程)
虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程. 一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界 ...
- 【学习笔记】Python基础教程学习笔记
教程视频网盘共享:http://pan.baidu.com/s/1hrTrR5E 03-python基础.if判断 print 输出数据 print("hahahah")----- ...
- 匿名内部类--毕向东java基础教程学习笔记
1.匿名内部类其实就是内部类的简写形式. 2.定义匿名内部类的前提: 该内部类必须继承一个类,或者实现一个接口. 3.匿名内部类的格式:new 父类名或接口名(){定义子类内容:} 4.其实匿名内部类 ...
- 内部类--毕向东Java基础教程学习笔记
内部类的访问规则 1. 内部类可以直接访问外部类的成员,包括私有. 之所以可以直接访问外部类的成员,是因为内部类中持有外部类的引用,格式:外部类名.this 2.外部类要访问内部类,必须建立内部类对象 ...
随机推荐
- __Linux__文件和目录
Linux 目录 /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录.所有的东西都是从这里开始.当你在终端里输入“/home”,你其实是在告诉电脑,先从/(根目录)开始,再进入到ho ...
- makefile中的shell编程注意点
参考:http://blog.csdn.net/wanglang3081/article/details/49423105 (1)Makefile本质上来讲也是shell脚本,即每条command都是 ...
- springboot2.X 集成redis+消息发布订阅
需求场景:分布式项目中,每个子项目有各自的 user 数据库, 在综合管理系统中存放这所有用户信息, 为了保持综合管理系统用户的完整性, 子系统添加用户后将用户信息以json格式保存至redis,然后 ...
- IEEE 754二进制浮点数算术标准
可能很多人都遇到过浮点数精度丢失的问题,下面以JavaScript为例. 1 - 0.9 = 0.09999999999999998 纳尼,不应该是0.1么,怎么变成0.099999999999999 ...
- how to use boost program options
From: http://www.radmangames.com/programming/how-to-use-boost-program_options If it so happens that ...
- Spring导出可以运行的jar包
最近需要解决Maven项目导入可执行的jar包的问题,如果项目不包含Spring,那么使用mvn assembly:assembly即可,详情可以参考:http://www.cnblogs.com/l ...
- JVM的7种垃圾收集器:主要特点 应用场景 设置参数 基本运行原理
原文地址:https://blog.csdn.net/tjiyu/article/details/53983650 下面先来了解HotSpot虚拟机中的7种垃圾收集器:Serial.ParNew.Pa ...
- Linux系统如何将某一程序设置为开机自启动
文章来源:百度知道. Linux开机启动程序详解 我们假设大家已经熟悉其它操作系统的引导过程,了解硬件的自检引导步骤,就只从Linux操作系统的引导加载程序(对个人电脑而言通常是LILO)开始,介绍L ...
- Swift 与 C 语言混合编程
前言 作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式. 1.基本 ...
- curl 调用jenkins的api
jenkins提供了rest api,通过调用接口,可以执行一些job的操作,如构建job ,新建job,启用禁用等操作骑车 其次curl是什么? cURL是一个利用URL语法在命令行下工作的文件传输 ...