上一篇继承里面我们说OOP里面的两个方面,一个是继承,那么另一个就是复合。
只有对象的组合才叫做复合。在Objective-C中,复合是通过包含作为实例变量的对象指针实现的。
例如:一辆汽车有6块玻璃、4个轮胎和1个发动机组成;
首先我们新建三个对象,分别是玻璃Glass、轮胎Tire和发动机Engine;
其次我们新建一个车Car对象;
关于Xcod中怎么新建对象,请看我的上一篇《【IOS开发之Objective-C】继承》里面有详细操作说明。
最后我们在Car对象中将玻璃Glass、车轮Tire和发动机Engine三个对象组合在一起。
具体实现:
// // Glass.h // 基本的复合 // // Created by qf on 15-7-11. // Copyright (c) 2015年 . All rights reserved. // #import <Foundation/Foundation.h> @interface Glass : NSObject @end
#import "Glass.h" @implementation Glass - (NSString *)description { return (@"A car has six glass."); } @end
// // Tire.h // 基本的复合 // // Created by qf on 15-7-11. // Copyright (c) 2015年 . All rights reserved. // #import <Foundation/Foundation.h> @interface Tire : NSObject @end
#import "Tire.h" @implementation Tire - (NSString *)description { return (@"A car has foue tires."); } @end
// // Engine.h // 基本的复合 // // Created by qf on 15-7-11. // Copyright (c) 2015年 . All rights reserved. // #import <Foundation/Foundation.h> @interface Engine : NSObject @end
#import "Engine.h" @implementation Engine - (NSString *)description { return (@"A car has one engine."); } @end我们可以看见三个类都是基于NSObject类的。表明每个类都是一个NSObjec,并且每个类都将继承NSObject类定义的所有行为。
下面再来看看类是怎么复合的。
// // Car.h // 基本的复合 // // Created by qf on 15-7-11. // Copyright (c) 2015年 . All rights reserved. // #import <Foundation/Foundation.h> #import "Glass.h" #import "Tire.h" #import "Engine.h" @interface Car : NSObject { Glass *glass; Tire *tire; Engine *engine; } - (void) print; @end
#import "Car.h" @implementation Car - (id) init { if(self = [super init]) { glass = [Glass new]; engine = [Engine new]; tire = [Tire new]; } return (self); } - (void) print { NSLog(@"%@",glass); NSLog(@"%@",engine); NSLog(@"%@",tire); } @end我们再来仔细看看Car对象的复合部分,是不是有点像C语言里面:我们先写Glass.c和Glass.h,Tire.c和Tire.h ……一直到把Car的写完,最后我们在Car.h里面包含其他三个.h头文件,最后我们就可以在car.c里面调用其他三个里面的函数了。
在车子的三个部分的类中,我们都可以看见一个description。
可以看见在函数:
- (NSString *)description { return (@"A car has one engine."); }返回的是一个NSString的指针,指针内容是:A car has one engine.其他两个也是一样的。
在三个类的复合部分,我们就能看见在Objective-C中,复合是通过包含作为实例变量的对象指针实现的。
这句话到底是怎么样的。
@interface Car : NSObject { Glass *glass; Tire *tire; Engine *engine; }每一个Car对象都会为glass、tire和engine的指针分配内存,但真正包含在Car中的并不是glass、tire和engine变量,只是内存中存在的其他对象的指针。为新建的Car对象分配内存是,这些指针都将被初始化为nil(零值)。
首先是初始化实例变量的init方法。该方法为我们的汽车创建了6个玻璃glass、4个轮胎和1个发动机变量。使用new创建新对象时,系统其实在后台执行了两步操作:第一步,为对象分配内存,即对象获得一个用来存放实例变量的内存块;第二步,自动调用init方法,是对象进入可使用状态。
在init方法中,有这么一个语句:
if(self = [super init])
为了让超类NSObject将初始化工作一部完成,需要调用[super init]。init方法返回值id类型数据,即泛型对象指针,就是被初始化的对象。将[super init]返回的结果赋给self是Objective-C的惯例。这么做是为了防止超类在初始化过程中返回对象与一开始创建的不一致。
再来看看main函数里面的。
// // main.m // 基本的复合 // // Created by qf on 15-7-11. // Copyright (c) 2015年 . All rights reserved. // #import <Foundation/Foundation.h> #import "Car.h" int main(int argc, const char * argv[]) { @autoreleasepool { Car *car; //创建一个Car类型的指针car car = [Car new]; //为car新建一个对象 [car print]; //调用print函数 打印输出 NSLog(@"Hello, World!"); } return 0; }main函数里面就比较简单了,看注释。
起初在看见俺这些代码的时候觉得很像C语言里面的一样,写几个.h和.c文件,让后就可以相互调用了。但这么其实和C语言里面的不一样。不然怎么会叫复合呢?呵呵,其实我也还不太懂。
我们需要学习descrption、super、init的使用。
最后还需要大量的联系其体会和理解什么是复合。