今天学习了Objective-C中有关类继承的知识。先纪录如下:
#import <Foundation/Foundation.h>
@interface Engine:NSObject
@end//Engine
@interface Tire:NSObject
@end// Tire
@interface Car:NSObject
{
Engine *carEngine;
Tire *carTire[4];
}
-(void)print;
@end//Car
#import "carPart.h"
@implementation Engine
-(NSString *)description
{
return(@"I am a Engine!");
}
@end//Engine
@implementation Tire
-(NSString *)description
{
return(@"I am a Tire!");
}
@end//Tire
@implementation Car
//注意init方法的返回值类型是id,即是一个指向对象的指针,该函数在用new创建对象时自动被调用
-(id) init
{
//需要先调用超类的init函数,并将结果赋给self;init调用会依据继承关系一直回调用到类关系的顶层。
if(self = [superinit])
{
carEngine = [Engine new];
carTire[0] = [Tire new];
carTire[1] = [Tire new];
carTire[2] = [Tire new];
carTire[3] = [Tire new];
}
//别忘了返回初始化后的对象指针
returnself;
}
-(void)print
{
//注意双引号字符串前必须加@符号
NSLog(@"%@",[carEnginedescription]);
NSLog(@"%@",[carTire[0] description]);
NSLog(@"%@",[carTire[1] description]);
NSLog(@"%@",[carTire[2] description]);
NSLog(@"%@",[carTire[3] description]);
}
@end//Car
int main(int argc, const char *argv[])
{
Car * carPart = [Car new];
[carPart print];
}
2)我们看到上面的程序发现,该结构比较死,如果我们能随时可以更换发动机和轮胎那么我们程序的机构就更灵活了。也许你发现了,这样修改是否像 策略模式 呢!
在这里使用存取方法来实现上述想法。
a)存取方法:用来读出或改变对象特定属性的方法。
存取方法分为setter 和 getter方法,一般setter方法前都是用"set"作为前缀;getter方法前不能有 "get"前缀。setter方法的命名基础是“set” + “属性名”;而 getter方法命名的基础就是“属性名”。
b)在cocoa中有“get”前缀的方法是有特殊意义的,如果“get”前缀出现在cocoa方法名称中,这就意味着该函数的返回值是通过该函数的参数返回的。
c)setter方法和getter方法一般上成对出现的,当然可以不成对出现,如对于只读特性只有getter方法,对于密码特性只有setter方法。
d)在Objective-C中所有对象之间的交互都是通过指针实现的。
修改后的程序如下:
头文件内容如下:
/*
* Composition2.h
* Composition2
*
* Created by yan li on 8/26/09.
* Copyright 2009 cat. All rights reserved.
*
*/
#import <Foundation/Foundation.h>
@interface Engine:NSObject
@end//Engine
@interface Tire:NSObject
@end// Tire
@interface Car:NSObject
{
Engine *carEngine;
Tire *carTire[4];
}
-(Engine *)carEngine;
-(void)setCarEngine:(Engine*)engine;
-(Tire*)carTireAtIndex:(int)index;
-(void)setCarTire:(Tire*)tire
AtIndex:(int)index;
-(void)print;
@end//Car
源文件内容如下:
//#import <Foundation/Foundation.h>
#import "Composition2.h"
@implementation Engine
-(NSString *)description
{
return(@"I am a Engine!");
}
@end//Engine
@implementation Tire
-(NSString *)description
{
return(@"I am a Tire!");
}
@end//Tire
@implementation Car
/*//注意init方法的返回值类型是id,即是一个指向对象的指针,该函数在用new创建对象时自动被调用
-(id) init
{
//需要先调用超类的init函数,并将结果赋给self;init调用会依据继承关系一直回调用到类关系的顶层。
if(self = [super init])
{
carEngine = [Engine new];
carTire[0] = [Tire new];
carTire[1] = [Tire new];
carTire[2] = [Tire new];
carTire[3] = [Tire new];
}
//别忘了返回初始化后的对象指针
return self;
}*/
-(Engine*)carEngine
{
return carEngine;
}
-(void)setCarEngine:(Engine*)engine
{
carEngine = engine;
}
-(Tire*)carTireAtIndex:(int)index
{
if(index > 3 || index < 0)
{
NSLog(@"index error");
exit(1);
}
return (carTire[index]);
}
//注意下面这个函数的名称的写法,比较独特以后会详细介绍
-(void)setCarTire:(Tire*)tire AtIndex:(int)index
{
//一下if 语句是防御性编程
if(index > 3 || index < 0)
{
NSLog(@"index error");
exit(1);
}
carTire[index] = tire;
}
-(void)print
{
//注意双引号字符串前必须加@符号
NSLog(@"%@",[carEngine description]);
NSLog(@"%@",[carTire[0] description]);
NSLog(@"%@",[carTire[1] description]);
NSLog(@"%@",[carTire[2] description]);
NSLog(@"%@",[carTire[3] description]);
}
@end//Car
int main(int argc, const char *argv[])
{
Car * carPart = [Car new];
// 在Car对象的调用代码中,使用对象属性setter方法随时修改对象的属性。
Engine *engine = [Engine new];
[carPart setCarEngine:engine];
int i;
//循环控制数要确认好
for(i = 0; i< 4; i++)
{
Tire *tire = [Tire new];
[carPart setCarTire:tire AtIndex:i];
}
[carPart print];
return0;
}
3)该程序我们还可以改进,我们不但可以随时为我们的汽车安装发动机和轮胎,而且我们使用“继承”技术我们可以不断的扩展新的发动机和轮胎,这样我们还可以为我们的汽车安装新品排的发动机和轮胎,挖塞!听其来好像是使用了策略模式编程思想喔