Objective-C之面向对象(二)

2017-10-10  本文已影响0人  吟风划彩虹

上一节简单地把“形状”这个概念写了一下,但是整体语言风格还是基于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

上一篇下一篇

猜你喜欢

热点阅读