ojective-C学习笔记(6)复合

通过之前的学习,知道了继承是在两个类之间建立关系的一种方式,它可以避免许多重复的代码。

使用复合可以组合多个对象,让它们分工协作。事实上,我们经常同时使用继承和复合来创建自己的类,掌握两个概念十分重要。

下面通过一个小程序来了解复合是什么。

//Tire类
@interface Tire : NSObject

@end

@implementation Tire

- (NSString *)description
{
    return [NSString stringWithFormat:@"I am a tire."];
}

@end

//Engien类
@interface Engine : NSObject

@end

@implementation Engine

- (NSString *)description
{
    return [NSString stringWithFormat:@"I am an engien."];
}

@end

//Car类,一辆汽车有一个引擎和4个轮子。
@interface Car : NSObject{
    Engine *engien;
    Tire *tires[4];
}

- (void)print;

@end

@implementation Car

- (instancetype) init{
    if(self = [super init]){
        engien = [Engine new];
        tires[0] = [Tire new];
        tires[1] = [Tire new];
        tires[2] = [Tire new];
        tires[3] = [Tire new];
    }
    return self;
}

- (void)print{
    NSLog(@"%@", engien);
    NSLog(@"%@", tires[0]);
    NSLog(@"%@", tires[1]);
    NSLog(@"%@", tires[2]);
    NSLog(@"%@", tires[3]);
}

@end

//main函数

int main(int argc, const char * argv[]) {
    Car *car = [[Car alloc] init];
    [car print];
    
    return 0;
}

输出结果为:

2018-04-21 20:00:26.610274+0800 Car[5750:735664] I am an engien.
2018-04-21 20:00:26.610512+0800 Car[5750:735664] I am a tire.
2018-04-21 20:00:26.610535+0800 Car[5750:735664] I am a tire.
2018-04-21 20:00:26.610548+0800 Car[5750:735664] I am a tire.
2018-04-21 20:00:26.610558+0800 Car[5750:735664] I am a tire.

上面的程序十分简单,可以添加一些存取方法让程序变得更加完善。

下面为Car添加一些setter和getter方法:

- (Engine*)engine{
    return engien;
}

- (void)setEngiene:(Engine *)newEngine{
    engien = newEngine;
}

- (Tire *)tireAtIndex:(int)index{
    if (index < 0 || index > 3){
        NSLog(@"error index (%d) in setTire:atIndex:", index);
        exit(1);
    }
    return tires[index];
}

- (void)setTire:(Tire *)tire atIndex:(int)index{
    if (index < 0 || index > 3){
        NSLog(@"error index (%d) in setTire:atIndex:", index);
        exit(1);
    }
    tires[index] = tire;
}

将main函数改为如下形式:

int main(int argc, const char * argv[]) {
    Car *car = [Car new];
    [car setEngiene:[Engine new]];
    for(int i = 0; i< 4; i++){
        [car setTire:[Tire new] atIndex:i];
    }
    [car print];
    
    return 0;
}

程序的运行结果并没有任何改变。

可以继续扩展上面的程序,创建Engine和Tire的子类,生成新型的引擎和轮子,组装更加豪华的汽车。这个程序同时用到了复合和继承。

复合还是继承?

学完了复合和继承,那么什么时候用复合,什么时候用继承呢?

继承的类之间建立的关系是“is a”(是一个),而复合的类之间建立的关系是“has a”(有一个)。

posted @ 2018-04-21 20:08  陈道长  阅读(122)  评论(0编辑  收藏  举报