年尾有点忙,objctive C的学习都放下了,趁有空补下课^_^
一、间接的理解
在编程界有句话,“只有多添加一个间接层,计算机科学没有解决不了的问题”。其实间接很简单,就是说不在代码中直接使用某个值,而使用指向该值的指针。
生活中的例子:你可能不知道KFC的电话号码,但你可以通过网上查找KFC的电话号码,使用网上查找实际就是一种间接地方式。
间接在程序上有多种表现方式,就例如变量式的间接、文件式间接、参数式间接。
二、OOP世界中的间接使用
其实OOP真正的革命性就是在调用代码中使用间接。
首先来个过程式编程的例子,好让大家容易理解OOP的思想。
#import <Foundation/Foundation.h> typedef enum{ kCircle, kRectangle, kOblateSpheroid } ShapeType; typedef enum{ kRedColor, kGreenColor, kBlueColor } ShapeColor; typedef struct{ int x, y, width, height; } ShapeRect; typedef struct{ ShapeType type; ShapeColor fillColor; ShapeRect bounds; } Shape; void drawShapes(Shape shapes[], int count){ int i; for(i = 0; i < count; i++){ switch (shapes[i].type) { case kCircle: drawCircle(shapes[i].bounds, shapes[i].fillColor); break; case kRectangle: drawRectang(shapes[i].bounds, shapes[i].fillColor); break; case kOblateSpheroid: drawEgg(shapes[i].bounds, shapes[i].fillColor); break; default: break; } } } void drawCircle(ShapeRect bounds, ShapeColor fillColor){ NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor)); } void drawRectang(ShapeRect bounds, ShapeColor fillColor){ NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor)); } void drawEgg(ShapeRect bounds, ShapeColor fillColor){ NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor)); } NSString *colorName(ShapeColor colorName){ switch(colorName){ case kRedColor : return @"red"; break; case kGreenColor : return @"green"; break; case kBlueColor: return @"blue"; break; } return @"no clue"; } int main(int argc, const char * argv[]){ Shape shapes[3]; ShapeRect rect0 = {0, 0, 10, 30}; shapes[0].type = kCircle; shapes[0].fillColor = kRedColor; shapes[0].bounds = rect0; ShapeRect rect1 = {30, 40, 50, 600}; shapes[1].type = kCircle; shapes[1].fillColor = kRectangle; shapes[1].bounds = rect1; ShapeRect rect2 = {15, 18, 37, 29}; shapes[2].type = kOblateSpheroid; shapes[2].fillColor = kBlueColor; shapes[2].bounds = rect2; drawShapes(shapes, 3); return (0); }
上面的代码灰常简单明了,但有一个问题是程序的扩展和维护变得很困难,如果我们多加一种类型,必须在项目中至少4个不同位置修改程序才能完成该任务。
以下说的OOP完美解决了这些问题,它以数据为中心,函数为数据服务。
void drawShapes(id shapes[], int count){ int i; for(i = 0; i < count; i++){ id shape = shapes[i]; [shape draw]; } }
上面的代码可能很多同学都感觉很奇怪,一般来说方括号在C语言中代表数组,在Objective C中,方括号还有其他的意思:它们通知某个对象该做什么。在方括号内,第一项是对象,其余部分是你需要对象执行的操作。在本例中,我们通知名称为shape的对象执行draw操作。如果shape是圆形,我们会得到圆形;如果shape是矩形,我们会的到矩形。
在Objective-C中,通知对象执行某种操作称为“发送消息”或者“调用方法”。代码中[shape draw]表示shape对象发送draw消息。
还有一个比较奇怪的地方就是id,id是一种泛型,用于表示任何种类的对象。实际id是一个指针,指向其中的某个结构。
三、面向对象的例子
以下是CirCle接口的声明
@interface Circle : NSObject{ ShapeColor fillColor; ShapeRect bounds; } - (void) setFillColor : (ShapeColor) fillColor; - (void) setBounds : (ShapeRect) bounds; - (void) draw; @end
@interface”告诉编译器这是objective C的声明的接口“。
Circle对象需要的各种数据成员:
{
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setBounds: (ShapeRect) bounds;
奇葩的objective,在方法声明的前面还多加个”-“,短线后面是方法的返回类型,位于圆括号中。接着后面的你们都懂的,就是参数的声明。
Circle的实现代码:
@implementation Circle -(void) setFillColor : (ShapeColor) c { fillColor =c; } -(void) setBounds : (ShapeRect) b { bounds = b; } -(void) draw { NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor)); } @end
跟声明接口一样,实现的也需要以@implementaction开头,结尾使用@end。
实际上objectvie - c中调用方法是,一个名为self的秘密隐藏参数被传递给接收对象。
以上例子中的fillColor = c,可以写成self->fillCOlor = c;
接下来最后一步实例化对象
实例化对象时,需要分配内存,然后这些内存被初始化并保存一些有用的默认值。
int main(int argc, const char * argv[]){ id shapes[3]; ShapeRect rect0 = {0, 0, 10, 30}; shapes[0] = [Circle new]; [shapes[0] setBounds : rect0]; [shapes[0] setFillColor : kRedColor]; ShapeRect rect1 = {30, 40, 50, 60}; shapes[1] = [Rectangle new]; [shapes[1] setBounds: rect1]; [shapes[1] setFillColor: kGreenColor]; ShapeRect rect2 = {15, 19, 37, 29}; shapes[2] = [OblateShereoid new]; [shapes[2] setBounds : rect2]; [shapes[2] setFillCOlor : kBlueColor]; drawShapes(shapes, 3); return (0); }
看上去,oop例子中的main方法跟过程化例子的main有点相似,oop例子中含有id数组,而不是shapes数组,创建对象时都需要发送new消息。
如果我们在程序上再添加一种类型,只需实现接口就可以扩展。
@implementation Triangle -(void) setFillColor : (ShapeColor) c { fillColor =c; } -(void) setBounds : (ShapeRect) b { bounds = b; } -(void) draw { NSLog(@"drawing a circle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor)); }
总结:
过程化编程:函数第一,数据第二
面向对象编程:数据第一、函数第二
相关推荐
通过以上内容的梳理,我们可以看出这门课程不仅教授学生如何使用Cocoa框架和Objective-C语言来开发Mac OS X应用程序,更重要的是通过实践项目让学生深入了解面向对象设计的原则,并掌握软件工程中的最佳实践。...
1. **Objective-C基础**:作为项目的基础,我们需要熟悉Objective-C的语法,包括类、对象、方法、属性、协议、分类等概念。OC是面向对象的语言,其消息传递机制和C++有所不同,学习如何创建和使用类是必不可少的。 ...
1. **Objective-C编程基础**:iPhone应用开发主要使用Objective-C语言,这是一种面向对象的编程语言,具有Smalltalk的消息传递特性和C/C++的语法结构。学习Objective-C的基础,包括类、对象、继承、消息传递等概念是...
在Objective-C中,这是一种面向对象的编程语言,主要用于苹果的 macOS 和 iOS 平台。实现"Hello, World!"的Objective-C代码如下: ```objc #import int main(int argc, const char * argv[]) { @autoreleasepool...
- **语言基础**:Objective-C 是一种面向对象的编程语言,是 iOS 开发的传统选择。了解其语法结构和面向对象编程的基本概念是非常重要的。 - **类和对象**:掌握如何定义类、实例化对象以及如何通过消息传递来调用...
两者都是面向对象的语言,但Swift的语法更加简洁,且支持类型推断,使代码更易读写。 3. **Cocoa Touch**:这是iOS应用的基础框架,提供了创建用户界面所需的类和API。UIKit是Cocoa Touch的核心,包含如...
- **Objective-C**是一种面向对象的编程语言,是MAC开发的主要语言之一。 - **Cocoa**是MAC OS X的一组API(应用程序接口),提供了构建图形用户界面和应用程序的基础。 2. **Core Data** - **Core Data**是一个...
通过以上章节的内容概览可以看出,《iOS 5 Programming Cookbook》涵盖了从基础的iOS开发概念到高级的面向对象编程技术,旨在帮助读者全面掌握iOS 5开发所需的技能。无论是对于初学者还是有经验的开发者来说,这本书...