大家好~由於最近都比較忙,趁着現在周末更新一下我的Objective-C學習筆記,好,現在開始。
1.什么是復合?在Objective-C 中,復合是通過包含作為實例變量的對象指針實現的:(我們定義一輛車有一個發動機和四個輪,程序如下)
[plain] view plaincopy
- #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方法。看看一下例子:
[plain] view plaincopy
- @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()函數:
[plain] view plaincopy
- 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