《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.外部类要访问内部类,必须建立内部类对象 ...
随机推荐
- android: 碎片的demo
现在你已经将关于碎片的重要知识点都掌握得差不多了,不过在灵活运用方面可能还有 些欠缺,因此又该进入我们本章的最佳实践环节了. 前面有提到过,碎片很多时候都是在平板开发当中使用的,主要是为了解决屏幕空间 ...
- C#模拟HTTP请求Post JSON
前言 因为接口是http的,我们站点是https的,不能https直接ajax请求http,所以需要在SharePoint中开发一个模拟请求Ajax的Service,分享一下. var httpWeb ...
- 图解 HTTP 协议
原文出处: BYSocket (@BYSocket) 一.技术基石及概述 问:什么是HTTP?答:HTTP是一个客户端和服务器端请求和响应的标准TCP.其实建立在TCP之上的. 当我们打开百度网页时, ...
- ReactNative: 搭建ReactNative开发环境
搭建ReactNative开发环境 不废话,具体步骤如下: 一.安装需要的软件 1.Homebrew Homebrew, Mac系统的包管理器,用于安装NodeJS和一些其他必需的工具软件. /usr ...
- 【Spark】榨干Spark性能-driver、exector内存突破256M
榨干Spark性能-driver.exector内存突破256M spark driver memory 256m_百度搜索 Spark executor.memory - CSDN博客 sparkd ...
- efcore数据库自动生成
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. p ...
- vue Object.defineProperty Proxy 数据双向绑定
Object.defineProperty 虽然已经能够实现双向绑定了,但是他还是有缺陷的. 只能对属性进行数据劫持,所以需要深度遍历整个对象 对于数组不能监听到数据的变化 虽然 Vue 中确实能检测 ...
- Mysql 用户和权限管理
用户和权限管理: 语法 grant 权限 on 数据库.数据表 to '用户' @ '主机名'; 例:给 xiaogang 分配所有的权限 grant all on *.* to 'xiaogang' ...
- 超级NB的防DDOS(小量级)攻击的脚本
# tree /usr/local/ddos/ /usr/local/ddos/ ├── ddos.conf ├── ddos.sh ├── ignore.ip.list └── LICENSE di ...
- github贡献开源项目
1.正常流程 1.拷贝项目到自己的github 2.本地修改后提交远程仓库 3.创建讨论Pull requests 4.开源项目者合并到master分支 5.删除仓库 2.快速发出讨论Pull req ...