大家好~由于最近都比较忙,趁着现在周末更新一下我的Objective-C学习笔记,好,现在开始。
1.什么是复合?在Objective-C 中,复合是通过包含作为实例变量的对象指针实现的:(我们定义一辆车有一个发动机和四个轮,程序如下)
- #import<Foundation/Foundation.h>
-
- @interface Tire : NSObject
- @end//Tire接口
- @implementation Tire
- - (NSString *) description
- {
- return(@"I am a tire, I last a while");
- }//description的实现
- @end//Tire的实现
-
- @interface Engine : NSObject
- @end//Engine接口
- @implementation Engine
- - (NSString *) description
- {
- return(@"I am an engine. Vroom!");
- }
- @end//Engine的实现
-
- @interface Car : NSObject
- {
- Engine *engine;
- Tire *tires[ 4 ];
- }
- - (void) print;
- @end//Car接口
- @Implementation Car
- - (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);
- }//init方法实现
- -(void) print
- {
- NSLog (@"%@" , engine);
- NSLog (@"%@" , tires[0]);
- NSLog (@"%@" , tires[1]);
- NSLog (@"%@" , tires[2]);
- NSLog (@"%@" , tires[3]);
- }//print方法的实现
- @end//Car的实现
- int main (int argc, const char * argv[ ])
- {
- Car *car;
- car = [ Car new];
- [ car print ];
- return (0);
- }//main :运行结果为,I am an engine, Vrooml
- I am a tire , I last a while.
- I am a tire , I last a while.
- I am a tire , I last a while.
- I am a tire , I last a while.
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2.下面我来详解看看这个程序要注意的一些地方:
(1)自定义NSLog( ):从上面程序我们可以看到轮和发动机都有一个description方法,程序运行时是这样的:NSlog( )给当前对象发送描述消息(description),r
然后对象的description方法生产一个NSString并返回,之后NSLog( )在其输出中包含这个字符串。在类中添加description方法就可以自定义NSLog( )如何输出对象
(2)engine和tires实例变量是复合的,因为它们是Car的实例变量。每个Car对象都会为指向engine和tires的指针分配内存,但是真正包含在Car中的并不是engine
和tires变量,而只是内存中存在的其他对象的引用。这些指针开始会被初始化为nil(零值)
(3)来看看Car类做了些什么,第一步,为对象分配内存,即对象获得一个用来存放其实例变量的内存块,第二步,自动调用init方法,让对象处于可以状态。
(4) if (self = [super init] )这句的具体含义在后面会说明。
3.存取方法:
(1)什么是存取方法?它是来读取或改变对象特定属性的方法。一般分为,setter方法和getter方法。看看一下例子:
- @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;
- @ens//Car
- @implementation Car
- -(Engine *) engine
- {
- return (engine);
- }//engine
- -(void )setEngine : (Engine *) newEngine
- {
- engine = newEngine;
- }//setEngine
- -(void) setTire : (Tire *) tire
- atindex : (int) index
- {
- if(index < 0 || index > 3){
- NSLog (@"bad index (%d) in setTire : atIndex : ", index);
- exit (1);
- }
- tires[ index ] = tire;
- }//seTire : atIndex :
- -(Tire *) tireAtIndex : (int) index
- {
- if( index < 0 || index >3){
- NSLog (@"bad index (%d) in "tireAtIndex :" , index );
- exit (1);
- }
- return (tires [ index ] );
- }//tireAtIndex :
- @end//Car的实现
- //////////////////////////////////////////////////////////////////////////////////////////////////////////
想实际使用这些存取方法,可以像下面这样写:Engine *engine = [ Engine new ] ;
[ car setEngine : engine ];
NSLog (@"the car Engine is %@" , [car engine]);
Tire *tire = [ Tire new ];
[car setTire : tire
atIndex : 2 ];
NSLog (@"tire number two is %@",[ car tireAtIndex : 2 ]);
4.以上程序需要注意的一些地方:
(1)setter方法根据它所更改的属性的名称来命名,并加上前缀”set“,而getter方法则仅仅根据其返回的属性名称来命名前面不加”get“
(2)在以上程序中可以看到:-(void) setTire : (Tire *) tire atindex : (int) index ,设置轮的方法,这方法这样写是什么意思呢?由于汽车的4个轮胎都有自己不同的位置,所以为汽车配置某个轮胎的时候,不仅要知道使用哪个轮胎,还要清楚每个轮在 汽车上的位置,同样,当访问汽车上某个轮胎时,也要指定这个轮的具体位置才行
5.添加了设置属性和获取属性等存储方法后对应的main()函数:
- int main (int argc, const char * argv[ ])
- {
- Car *car = [Car new];
- Engine *engine = [Engine new];
- [ car setEngine : engine ];
- int i;
- for (i = 0 ; i <4 ; i++){
- Tire *tire = [ Tire new];
- [car setTire : tire
- atIndex : i ];
- }
- [ car print ];
- return(0);
- }//main,输出结果与之前一样
-
6.另外我们还可以自定义两个类,分别继承Engine和Tire,并且可以对它的方法复写。具体怎么复合和继承配合使用这里就不多说了,比较简单~
7.判断是复合还是继承的方法很简单:当某件事物里有什么这是复合,当某事物是什么这是继承,用这个方法就能简单的把它们区分开来。
好了,这篇就在这里结束了~继续会有更新~~~转载请注明:http://blog.csdn.net/yuzhiboyi