不写过多文字,直接上代码表示
一、Interface 定义
@interface Circle : NSObject
{
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end // Circle
二、Circle实现
@implementation Circle
- (void) setFillColor: (ShapeColor) c
{
fillColor = c;
} // setFillColor
- (void) setBounds: (ShapeRect) b
{
bounds = b;
} // setBounds
- (void) draw
{
NSLog (@"drawing a circle at (%d %d %d %d) in %@",
bounds.x, bounds.y,
bounds.width, bounds.height,
colorName(fillColor));
} // draw
@end // Circle
三、相同可以用相同的方法实现:OblateSphereoid 和 Rectangle
四、使用方法:
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] = [OblateSphereoid new];
[shapes[2] setBounds: rect2];
[shapes[2] setFillColor: kBlueColor];
drawShapes (shapes, 3);
return (0);
} // main
五、派生
对于各种形状的 setFillColor 和 setBounds 是重复代码。
@interface Shape : NSObject
{
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) fillColor;
- (void) setBounds: (ShapeRect) bounds;
- (void) draw;
@end // Shape
实现Shape.
@implementation Shape
- (void) setFillColor: (ShapeColor) c
{
fillColor = c;
} // setFillColor
- (void) setBounds: (ShapeRect) b
{
bounds = b;
} // setBounds
- (void) draw
{
} // draw
@end // Shape
实现 Circle
@implementation Circle
- (void) draw
{
NSLog (@"drawing a circle at (%d %d %d %d) in %@",
bounds.x, bounds.y,
bounds.width, bounds.height,
colorName(fillColor));
} // draw
@end // Circle
实现 Rectangle
@implementation Rectangle
- (void) draw
{
NSLog (@"drawing rect at (%d %d %d %d) in %@",
bounds.x, bounds.y,
bounds.width, bounds.height,
colorName(fillColor));
} // draw
@end // Rectangle
六、函数重载
Circle 要改变 setFillColor 行为
@implementation Circle
- (void) setFillColor: (ShapeColor) c
{
if (c == kRedColor) {
c = kGreenColor;
}
[super setFillColor: c];
} // setFillColor
// 其它Circle 部分代码不变
@end // Circle
七、组合
Class tire
@interface Tire : NSObject
@end // Tire
@implementation Tire
- (NSString *) description
{
return (@"I am a tire. I last a while");
} // description
@end // Tire
Class Engine
@interface Engine : NSObject
@end // Engine
@implementation Engine
- (NSString *) description
{
return (@"I am an engine. Vrooom!");
} // description
@end // Engine
@interface Car : NSObject
{
Engine *engine;
Tire *tires[4];
}
- (void) print;
@end // Car
@implementation Car
- (id) init
{
//一种 Object-C 通用的初始化方法
if (self = [super init]) {
engine = [Engine new];
tires[0] = [Tire new];
tires[1] = [Tire new];
tires[2] = [Tire new];
tires[3] = [Tire new];
}
return (self);
} // init
- (void) print
{
NSLog (@"%@", engine);
NSLog (@"%@", tires[0]);
NSLog (@"%@", tires[1]);
NSLog (@"%@", tires[2]);
NSLog (@"%@", tires[3]);
} // print
@end // Car
int main (int argc, const char * argv[])
{
Car *car;
car = [Car new];
[car print];
return (0);
} // main
Result:
I am an engine. Vrooom!
I am a tire. I last a while.
I am a tire. I last a while.
I am a tire. I last a while.
I am a tire. I last a while.
八、getter 和 setter
@interface Car : NSObject
{
Engine *engine;
Tire *tires[4];
}
//注意:对于 getter 方法不使用getEngie 的命令方式,而是直接使用 engine.
//get 在 Cocoa 中有特殊含义,
//The word “get” has a special meaning in Cocoa: in a Cocoa method name, it means the method returns a value via a pointer that you pass in as a parameter.
- (Engine *) engine;
- (void) setEngine: (Engine *) newEngine;
- (Tire *) tireAtIndex: (int) index;
- (void) setTire: (Tire *) tire
atIndex: (int) index;
- (void) print;
@end // Car
@implement
- (Engine *) engine
{
return (engine);
} // engine
- (void) setEngine: (Engine *) newEngine
{
engine = newEngine;
} // setEngine
- (void) setTire: (Tire *) tire
atIndex: (int) index
{
if (index < 0 || index > 3) {
NSLog (@"bad index (%d) in setTire:atIndex:", index);
exit (1);
}
tires[index] = tire;
} // setTire:atIndex:
- (Tire *) tireAtIndex: (int) index
{
if (index < 0 || index > 3) {
NSLog (@"bad index (%d) in "tireAtIndex:",index);
exit (1);
}
return (tires[index]);
} // tireAtIndex
@end
int main (int argc, const char * argv[])
{
Car *car = [Car new];
Engine *engine = [Engine new];
[car setEngine: engine];
int i;
for (i = 0; i < 4; i++) {
Tire *tire = [Tire new];
[car setTire: tire atIndex: i];
}
[car print];
return (0);
} // main
//输出
I am an engine. Vrooom!
I am a tire. I last a while.
I am a tire. I last a while.
I am a tire. I last a while.
I am a tire. I last a while.
九、扩展
@interface Slant6 : Engine
@end // Slant6
@implementation Slant6
- (NSString *) description
{
return (@"I am a slant- 6. VROOOM!");
} // description
@end // Slant6
@interface AllWeatherRadial : Tire
@end // AllWeatherRadial
@implementation AllWeatherRadial
- (NSString *) description
{
return (@"I am a tire for rain or shine.");
} // description
@end // AllWeatherRadial
int main (int argc, const char * argv[])
{
Car *car = [Car new];
int i;
for (i = 0; i < 4; i++) {
Tire *tire = [AllWeatherRadial new];
[car setTire: tire
atIndex: i];
}
Engine *engine = [Slant6 new];
[car setEngine: engine];
[car print];
return (0);
} // main
Composition or Inheritance?
Composition = has a; Inheritance = is a.