您好,登錄后才能下訂單哦!
你已經看到處理分數的方法如何通過名稱直接訪問兩個實例變量numerator和denominator。事實上,實例方法總是可以直接訪問它的實例變量的。然而,類方法則不能,因為它只處理本身,并不處理任何類實例(仔細想想)。但是,如果要從其他位置訪問實例變量,例如,從main函數內部來訪問,該如何實現?在這種情況下,不能直接訪問這些實例變量,因為它們是隱藏的。將實例變量隱藏起來的這種做法實際上涉及一個關鍵概念——“數據封裝”。它使得編寫定義的人在不必擔心程序員(即類的使用者)是否破壞類的內部細節的情況下,擴展和修改其定義。數據封裝提供了程序員和其他開發者之間的良好隔離層。
通過編寫特殊方法來檢索實例變量的值,可以用一種新的方式來訪問它們。編寫setNumerator:和setDenominator:方法用于給Fraction類的兩個實例變量設定值。為了獲取這些實例變量的值,我們需要編寫新的方法。例如,創建兩個名為numerator和denominator的新方法,用于訪問相應的Fraction實例變量,這些實例是消息的接收者。結果是對應的整數值,你將返回這些值。以下是這兩個新方法的聲明:
–(int) numerator;
–(int) denominator;
下面是定義:
–(int) numerator
{
return numerator;
}
–(int) denominator
{
return denominator;
}
注意,它們訪問的方法名和實例變量名是相同的,這樣做不存在任何問題(雖然似乎有些奇怪)。事實上,這是很常見的情況。代碼清單3-4用來測試這兩個新方法。
代碼清單3-4
// 訪問實例變量的程序 – cont'd
#import <Foundation/Foundation.h>
//---- @interface 部分 ----
@interface Fraction: NSObject
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
-(int) numerator;
-(int) denominator;
@end
//---- @implementation 部分 ----
@implementation Fraction
{
int numerator;
int denominator;
}
-(void) print
{
NSLog (@"%i/%i", numerator, denominator);
}
-(void) setNumerator: (int) n
{
numerator = n;
}
-(void) setDenominator: (int) d
{
denominator = d;
}
-(int) numerator
{
return numerator;
}
-(int) denominator
{
return denominator;
}
@end
//---- program 部分 ----
int main (int argc, char *argv[])
{
@autoreleasepool {
Fraction *myFraction = [[Fraction alloc] init];
// 設置分數為1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
// 使用兩個新的方法顯示分數
NSLog (@"The value of myFraction is: %i/%i",
[myFraction numerator], [myFraction denominator]);
}
return 0;
}
代碼清單3-4 輸出
The value of myFraction is 1/3
NSLog語句顯示發送給myFraction:的兩條消息的結果,第一條消息檢索numerator的值,第二條則檢索denominator的值。
NSLog (@"The value of myFraction is: %i/%i",
[myFraction numerator], [myFraction denominator]);
在第一條消息調用時,numerator消息會發送給Fraction類的對象myFraction。在這個方法中,分數中numerator的實例變量的值被返回。記住,方法執行的上下文環境就是接收到消息的對象。當訪問numerator方法并且返回numerator實例變量值的時候,會取得myFraction的分子并返回,返回的整數傳入NSLog,從而顯示出來。第二條消息調用時,denominator方法會被調用并返回myFraction的分母,它仍通過NSLog顯示。
順便說一下,設置實例變量值的方法通常總稱為設值方法(setter),而用于檢索實例變量值的方法叫做取值方法(getter)。對Fraction而言,setNumerator:和setDenominator:是設值方法,numerator和denominator是取值方法。取值方法和設值方法通常稱為訪問器(accessor)方法。
確定你已經理解了設值方法和取值方法的不同。設值方法不會返回任何值,因為其主要目的是將方法參數設為對應的實例變量的值。在這種情況下并不需要返回值。另一方面,取值方法的目的是獲取存儲在對象中的實例變量的值,并通過程序返回發送出去。基于此目的,取值方法必須返回實例的值作為return的參數。
你不能在類的外部編寫方法直接設置或獲取實例變量的值,而需要編寫設值方法和取值方法來設置或獲取實例變量的值,這便是數據封裝的原則。你必須通過使用一些方法來訪問這些通常對“外界”隱藏的數據。這種做法集中了訪問實例變量的方式,并且能夠阻止其他一些代碼直接改變實例變量的值。如果可以直接改變,會讓程序很難跟蹤、調試和修改。
這里還應指出,還有一個名為new的方法可以將alloc和init的操作結合起來。因此,程序行
Fraction *myFraction = [Fraction new];
可用于創建和初始化新的Fraction。但用兩步來實現創建和初始化的方式通常更好,這樣可以在概念上理解正在發生兩個不同的事件:首先創建一個對象,然后對它初始化。
本文節選自《Objective-C 程序設計(第4版)》
電子工業出版社出版
[美]Stephen G. Kochan(斯蒂芬·G·科昌)著
林冀 范俊朱奕欣譯
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。