間接(indirection)
"只要再多添加一層間接猫胁,計(jì)算機(jī)科學(xué)中就沒(méi)有解決不了的問(wèn)題位他。"
- 例子
- 電話薄
- 讓他人代替你自己去完成工作
- 編寫一段代碼來(lái)查詢其他代碼便脊,并通過(guò)它繼續(xù)訪問(wèn)另一層代碼驹溃。
- 推諉
- 變量與間接
- 使用文件名的間接
在面向?qū)ο缶幊讨惺褂瞄g接
使用間接來(lái)調(diào)用代碼付呕,不是直接調(diào)用某個(gè)函數(shù),而是間接調(diào)用娃磺。
- 過(guò)程式編程(Procedual Programming)
#import <Foundation/Foundation.h>
typedef enum {
kCircle,
kRectangle,
kEgg,
} ShapeType;
typedef enum {
kRedColor,
kGreenColor,
kBlueColor
} ShapeColor;
//不同圖形元素
typedef struct {
int x, y, width, height;
} ShapeRect;
//圖形結(jié)構(gòu)
typedef struct {
ShapeType type;
ShapeColor fillColor;
ShapeRect bounds;
} Shape;
//顏色函數(shù)
NSString *colorName(ShapeColor fillColor)
{
switch (fillColor) {
case kRedColor:
return @"red";
break;
case kGreenColor:
return @"green";
break;
case kBlueColor:
return @"blue";
break;
}
return @"no clue";
}
//繪制圖形
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 drawRectangle(ShapeRect bounds, ShapeColor fillColor)
{
NSLog(@"drawing a Rectangle 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 Egg at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));
}
void drawShapes(Shape shapes[], int count)
{
for (int i=0; i<count; i++) {
switch (shapes[i].type) {
case kCircle:
drawCircle(shapes[i].bounds, shapes[i].fillColor);
break;
case kRectangle:
drawRectangle(shapes[i].bounds, shapes[i].fillColor);
break;
case kEgg:
drawEgg(shapes[i].bounds, shapes[i].fillColor);
break;
default:
break;
}
}
}
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, 60};
shapes[1].type = kRectangle;
shapes[1].fillColor = kGreenColor;
shapes[1].bounds = rect1;
ShapeRect rect2 = {15, 18, 37, 29};
shapes[2].type = kEgg;
shapes[2].fillColor = kBlueColor;
shapes[2].bounds = rect2;
drawShapes(shapes, 3);
return 0;
}
修改過(guò)去正常工作的代碼很可能會(huì)引入新的錯(cuò)誤薄湿。
建立在函數(shù)之上,數(shù)據(jù)為函數(shù)服務(wù)偷卧。
代碼例子 3.2.1 Shapes-Procedural
- 面向?qū)ο缶幊?
- 以數(shù)據(jù)為中心豺瘤,函數(shù)為數(shù)據(jù)服務(wù)
- 代碼例子
3.2.2 Shapes-Object
-
id
是一種泛型听诸,可以用來(lái)引用任何類型的對(duì)象(id實(shí)際上是一個(gè)指向結(jié)構(gòu)體的指針)坐求。 - 方括號(hào)在OC中其他意義:用于通知某個(gè)對(duì)象該去做什么。
[shape draw];
表示通知shape對(duì)象執(zhí)行draw操作 - 發(fā)送消息(調(diào)用方法):通知對(duì)象執(zhí)行某種操作晌梨。
- 類是一種能夠?qū)嵗蓪?duì)象的結(jié)構(gòu)體桥嗤。
- 如果在運(yùn)行時(shí)改變某個(gè)類,則該類的所有對(duì)象自動(dòng)繼承這些變化仔蝌。
#import <Foundation/Foundation.h>
typedef enum {
kRedColor,
kGreenColor,
kBlueColor
} ShapeColor;
//不同圖形元素
typedef struct {
int x, y, width, height;
} ShapeRect;
//顏色函數(shù)
NSString *colorName(ShapeColor fillColor)
{
switch (fillColor) {
case kRedColor:
return @"red";
break;
case kGreenColor:
return @"green";
break;
case kBlueColor:
return @"blue";
break;
}
return @"no clue";
}
@interface Circle : NSObject
{
@private
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end //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
@interface Rectangle : NSObject
{
@private
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end //Rectangle
@implementation Rectangle
- (void) setFillColor:(ShapeColor) c
{
fillColor = c;
}
- (void) setBounds:(ShapeRect) b
{
bounds = b;
}
- (void) draw
{
NSLog(@"drawing a Rectangle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));
}
@end
@interface Egg : NSObject
{
@private
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end //Egg
@implementation Egg
- (void) setFillColor:(ShapeColor) c
{
fillColor = c;
}
- (void) setBounds:(ShapeRect) b
{
bounds = b;
}
- (void) draw
{
NSLog(@"drawing a Egg at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));
}
@end
// 補(bǔ)充一個(gè)三角形
@interface Triangle : NSObject
{
@private
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end //Triangle
@implementation Triangle
- (void) setFillColor:(ShapeColor) c
{
fillColor = c;
}
- (void) setBounds:(ShapeRect) b
{
bounds = b;
}
- (void) draw
{
NSLog(@"drawing a Triangle at (%d %d %d %d) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));
}
@end
void drawShapes(id shapes[], int count)
{
for (int i=0; i<count; i++) {
id shape = shapes[i];
[shape draw];
}
}
int main(int argc, const char * argv[]) {
id shapes[4];
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, 18, 37, 29};
shapes[2] = [Egg new];
[shapes[2] setBounds:rect2];
[shapes[2] setFillColor:kBlueColor];
ShapeRect rect3 = {3, 4, 5, 0};
shapes[3] = [Triangle new];
[shapes[3] setBounds:rect3];
[shapes[3] setFillColor:kBlueColor];
drawShapes(shapes, 4);
return 0;
}
有關(guān)術(shù)語(yǔ)
- class
- object
- instance
- message
- method
- method dispatcher
- interface
- implementation
OC中的OOP
@interface Circle : NSObject
{
@private
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end //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
-
@interface
OC編譯器需要一些有關(guān)類的信息-
@
可以看成是對(duì)C語(yǔ)言的擴(kuò)展 -
instance variable(實(shí)例變量) :
@interface
下的花括號(hào)的內(nèi)容:
{ @private ShapeColor fillColor; ShapeRect bounds; }
-
method declaration(方法聲明)泛领。有點(diǎn)像C語(yǔ)言中的函數(shù)原型。
-
表示對(duì)象方法敛惊,+
表示類方法渊鞋。(void)
表示返回類型。
- (void) setFillColor: (ShapeColor) fillColor; - (void) setBounds: (ShapeRect) bounds; - (void) draw;
-
infix notation(中綴符) : 方法的名稱及其參數(shù)都是合在一起的
[circle setFillColor: kRedColor]
表示調(diào)用帶一個(gè)參數(shù)的方法 - 如果方法使用參數(shù)瞧挤,則需要冒號(hào)锡宋,否則不需要冒號(hào)
- 提倡@end語(yǔ)言后添加注釋來(lái)注明類的名稱
-
-
@implementation
- @implementation中可以定義在@interface中聲明過(guò)和沒(méi)有聲明過(guò)的方法
- OC中不存在真正的私有方法
-
實(shí)例化對(duì)象
- instantiation(實(shí)例化)
-
[Circle new]
發(fā)送new消息
軟件實(shí)體應(yīng)該對(duì)擴(kuò)展開(kāi)放,而對(duì)修改關(guān)閉特恬。 ---- 開(kāi)放/關(guān)閉原則(Bertrand Meyer)