Objective-C第五章中复合类型有哪些详细讲解?

2026-05-22 19:111阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1142个文字,预计阅读时间需要5分钟。

目录 + Objective-C + 基础教程第五章,复合 + 什么是复合? + Car程序 + 自定义NSLog() + 存取方法get Set Tires(轮胎) + 存取方法 + Car类代码的其他变化 + 扩展Car程序 + 复合还是继承 + 小结 + Objective-C + 基础教程第五章

目录
  • Objective-C 基础教程第五章,复合
    • 什么是复合?
      • Car程序
    • 自定义NSLog()
    • 存取方法get Set
      • Tires(轮胎) 存取方法
      • Car类代码的其他变化
    • 扩展Car程序
    • 复合还是继承
    • 小结

Objective-C 基础教程第五章,复合 什么是复合?

编程中的复合(composition)就好像音乐中的作曲(composition)一样:将多个组件组合在一起,配合使用,从而得到完整的作品。

Car程序

接下来我们不再用shape作为例子来写代码了,这次用car作为例子写代码,我们先来看看如何搭建汽车模型。

1辆汽车只需要1台发动机和4个轮胎。

mainCarParts.m

#import <Foundation/Foundatin.h> /* 汽车轮胎 */ @interface Tire : NSObject @end @implementation Tire - (NSString*) description{ return (@"I' am a tire. I last a while."); } @end

/* 汽车发动机 */ @interface Engine : NSObject @end @implementation Engine - (NSString*) description{ return (@"I am an engine. Vroom!"); } @end

/* * 汽车 */ @interface Car: NSObject { //复合概念 Engine *engine; Tire *tires[4]; //因为engine和tires是Car类的实例变量,所以他们是复合的。 //你可以说 汽车是由4个轮胎和一个发动机组成的。(但是人们一般不会这么说) } //可以这么说 汽车有4个轮胎和一个发动机 -(void) print; @end @implementation Car//Car的init方法创建了4个新轮胎 并赋值给tires数组,还创建了一台发送机并赋值给engine实例变量。 -(id) init{ if(self == [super init]){ engine = [Engine new]; tires[0] = [Tire new]; tires[1] = [Tire new]; tires[2] = [Tire new]; tires[3] = [Tire new]; } return (self) } -(void) print { NSLog(@"%@",engine); for(int i=0;i<4;i++) { NSLog(@"%@",tires[i]); } } @end

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

Tips:(如果类中没有包含任何实例变量,便可以省略掉接口定义中的花括号。)

自定义NSLog()

NSLog可以通过%@来输出对象。NSLog处理%@说明符时,会询问参数列表中相应的对象以得到这个对象的描述。

技术原理上是NSLog给这个对象发送了description消息,然后对象的description方法生成了一个NSString并将其返回。在类中提供description方法就可以自定义NSLog()会如何输出对象。

存取方法get Set

编程人员很少会对自己编写的程序感到满意,因为软件开发是永无止境的,永远有bug要去修正。

我们可以使用存取方法来改进它,使它的代码更灵活。

存取(accessor)方法是用来读取或改变某个对象属性的方法。

settter存取方法之存方法。

getter存取方法之取方法。

我们在写代码的时候最好不要直接改变类实例变量的值,比如在main函数中car->engine改变值,应该使用setter方法改变,这也算是间接工作的一个例子。

@interface Car:NSObject { Engine *engine; Tire *tires[4]; } -(Engine *)engine; -(void) SetEngine:(Engine *) newEngine; -(Tire*) tireAtIndex:(int) index; -(void) SetTire:(Tire*) tire atIndex:(int) index; -(void) print; @end

@implementation Car - (Engine*) engine { return (engine); } -(void) SetEngine:(Engine*) newEngine { engine = newEngine; } @end //getter方法engine返回实例变量engine的当前值,Objective-C中所有对象间的交互都是通过指针实现的。 //setter方法让engine指针 指向了newEngine,

int main() { Engine *engine = [Engine new]; [car SetEngine:engine]; NSLog(@"the car's engine is %@",[car engine]); } Tires(轮胎) 存取方法

-(void) setTire:(Tire*) tire atIndex:(int) index; -(Tire*) tireAtIndex:(int) index;

由于汽车的4个轮胎都有自己不同的位置,所以Car对象中包含一个轮胎的数组。

在这里我们需要用索引存取器而不能直接访问tires数组。

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

Tire *tire = [Tire new]; [car setTire:tire atIndex:2]; NSLog(@"tire number two is %@",[car tireAtIndex:2]); Car类代码的其他变化

Car类的init方法。因为我们有了能够访问engine和tire变量的方法,所以我们不再需要创建这两个变量了,可以直接从外部进行控制,(而是由创建汽车的代码来负责配置发动机和轮胎)。所以我们可以完全剔除init方法

ps:新车的车主会得到一辆没有轮胎和发动机的汽车,不过装配是轻而易举的事(有时软件中的生活比现实生活要容易的多啊

本文共计1142个文字,预计阅读时间需要5分钟。

目录 + Objective-C + 基础教程第五章,复合 + 什么是复合? + Car程序 + 自定义NSLog() + 存取方法get Set Tires(轮胎) + 存取方法 + Car类代码的其他变化 + 扩展Car程序 + 复合还是继承 + 小结 + Objective-C + 基础教程第五章

目录
  • Objective-C 基础教程第五章,复合
    • 什么是复合?
      • Car程序
    • 自定义NSLog()
    • 存取方法get Set
      • Tires(轮胎) 存取方法
      • Car类代码的其他变化
    • 扩展Car程序
    • 复合还是继承
    • 小结

Objective-C 基础教程第五章,复合 什么是复合?

编程中的复合(composition)就好像音乐中的作曲(composition)一样:将多个组件组合在一起,配合使用,从而得到完整的作品。

Car程序

接下来我们不再用shape作为例子来写代码了,这次用car作为例子写代码,我们先来看看如何搭建汽车模型。

1辆汽车只需要1台发动机和4个轮胎。

mainCarParts.m

#import <Foundation/Foundatin.h> /* 汽车轮胎 */ @interface Tire : NSObject @end @implementation Tire - (NSString*) description{ return (@"I' am a tire. I last a while."); } @end

/* 汽车发动机 */ @interface Engine : NSObject @end @implementation Engine - (NSString*) description{ return (@"I am an engine. Vroom!"); } @end

/* * 汽车 */ @interface Car: NSObject { //复合概念 Engine *engine; Tire *tires[4]; //因为engine和tires是Car类的实例变量,所以他们是复合的。 //你可以说 汽车是由4个轮胎和一个发动机组成的。(但是人们一般不会这么说) } //可以这么说 汽车有4个轮胎和一个发动机 -(void) print; @end @implementation Car//Car的init方法创建了4个新轮胎 并赋值给tires数组,还创建了一台发送机并赋值给engine实例变量。 -(id) init{ if(self == [super init]){ engine = [Engine new]; tires[0] = [Tire new]; tires[1] = [Tire new]; tires[2] = [Tire new]; tires[3] = [Tire new]; } return (self) } -(void) print { NSLog(@"%@",engine); for(int i=0;i<4;i++) { NSLog(@"%@",tires[i]); } } @end

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

Tips:(如果类中没有包含任何实例变量,便可以省略掉接口定义中的花括号。)

自定义NSLog()

NSLog可以通过%@来输出对象。NSLog处理%@说明符时,会询问参数列表中相应的对象以得到这个对象的描述。

技术原理上是NSLog给这个对象发送了description消息,然后对象的description方法生成了一个NSString并将其返回。在类中提供description方法就可以自定义NSLog()会如何输出对象。

存取方法get Set

编程人员很少会对自己编写的程序感到满意,因为软件开发是永无止境的,永远有bug要去修正。

我们可以使用存取方法来改进它,使它的代码更灵活。

存取(accessor)方法是用来读取或改变某个对象属性的方法。

settter存取方法之存方法。

getter存取方法之取方法。

我们在写代码的时候最好不要直接改变类实例变量的值,比如在main函数中car->engine改变值,应该使用setter方法改变,这也算是间接工作的一个例子。

@interface Car:NSObject { Engine *engine; Tire *tires[4]; } -(Engine *)engine; -(void) SetEngine:(Engine *) newEngine; -(Tire*) tireAtIndex:(int) index; -(void) SetTire:(Tire*) tire atIndex:(int) index; -(void) print; @end

@implementation Car - (Engine*) engine { return (engine); } -(void) SetEngine:(Engine*) newEngine { engine = newEngine; } @end //getter方法engine返回实例变量engine的当前值,Objective-C中所有对象间的交互都是通过指针实现的。 //setter方法让engine指针 指向了newEngine,

int main() { Engine *engine = [Engine new]; [car SetEngine:engine]; NSLog(@"the car's engine is %@",[car engine]); } Tires(轮胎) 存取方法

-(void) setTire:(Tire*) tire atIndex:(int) index; -(Tire*) tireAtIndex:(int) index;

由于汽车的4个轮胎都有自己不同的位置,所以Car对象中包含一个轮胎的数组。

在这里我们需要用索引存取器而不能直接访问tires数组。

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

Tire *tire = [Tire new]; [car setTire:tire atIndex:2]; NSLog(@"tire number two is %@",[car tireAtIndex:2]); Car类代码的其他变化

Car类的init方法。因为我们有了能够访问engine和tire变量的方法,所以我们不再需要创建这两个变量了,可以直接从外部进行控制,(而是由创建汽车的代码来负责配置发动机和轮胎)。所以我们可以完全剔除init方法

ps:新车的车主会得到一辆没有轮胎和发动机的汽车,不过装配是轻而易举的事(有时软件中的生活比现实生活要容易的多啊