上一节简单地把“形状”这个概念写了一下,但是整体语言风格还是基于C++写的,本节我们把上一节的内容改变为基于Objective-C风格的代码,修改的地方不多,主要是以下几个地方:
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 kOblateSpheroid:
drawOblateSpheroid(shapes[i].bounds, shapes[i].fillColor);
break;
default:
break;
}
}
}
首先是drawShapes函数的改变,原来通过switch来判断shape的类型,进而来绘制shape,通过Objective-C的“id”关键字,我们可以实现多态效果:
void drawShapes(id shapes[], int count)
{
for (int i = 0; i < count; ++i) {
id shape = shapes[i];
[shape draw];
}
}
然后是类的构建,我们分别通过@interface定义Circle,Retangle以及OlateSpheroid类:
// the interface of Class Circle
@interface Circle: NSObject
{
ShapeColor fillColor;
ShapeRect bounds;
}
- (void) setFillColor: (ShapeColor) color;
- (void) setBounds: (ShapeRect) bs;
- (void) draw;
@end
@implementation Circle
- (void) setFillColor:(ShapeColor)color
{
fillColor = color;
} // setFillColor
- (void) setBounds:(ShapeRect)bs
{
bounds = bs;
} // setBounds
- (void) draw
{
NSLog(@"draw a circle at ( %d %d %d %d ) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));
}
@end // circle
Retangle 和 OlateSpheroid类的定义以及实现与Circle类是完全一致的,就是draw函数的输出稍微修改一下log而已:
- (void) draw
{
NSLog(@"draw a Rectangle at ( %d %d %d %d ) in %@", bounds.x, bounds.y, bounds.width, bounds.height, colorName(fillColor));
}
主函数中调用部分,需要构建对应的Circle类,Retangle类等:
int main(int argc, const char * argv[]) {
@autoreleasepool {
id shapes[3];
ShapeRect rect0 = {0, 0, 10, 30};
shapes[0] = [Circle new];
[shapes[0] setFillColor:kRedColor];
[shapes[0] setBounds:rect0];
ShapeRect rect1 = {10, 30, 20, 40};
shapes[1] = [Rectangle new];
[shapes[1] setFillColor:kGreenColor];
[shapes[1] setBounds:rect1];
ShapeRect rect2 = {20, 40, 30 ,50};
shapes[2] = [OlateSpheroid new];
[shapes[2] setFillColor:kBlueColor];
[shapes[2] setBounds:rect2];
drawShapes(shapes, 3);
}
return 0;
}
这样写虽然加入了部分多态的内容,但是代码重复率还是很高,比较冗余,下一节我们采用继承的方法再来修改这部分代码。
该部分内容代码详见 github。
网友评论