2012-10-02 26 views
0

我正在學習Objective-C世界中的第一個絆腳石,並附上一本關於該主題的書。我現在已經到了將創建和使用自定義類的概念內化的階段。魔術師和自定義課程 - 瞭解頭文件和實現文件

正如我認爲,正確理解這些基本概念和原則是我將來學習Objective-C的關鍵,我只是想與您覈對一下,是否已經在某種程度上正確理解了這些概念。

所以當創建自定義類時,我已經理解這是在兩個單獨的文件 - 公共類頭文件和類實現文件中完成的。爲了內化這個概念,我將這個概念隱喻地理解爲與在觀衆面前做技巧的「魔術師」並行。

頭文件有點像魔術師執行劇場外的海報。在進入之前,我們都可以看到魔術師看起來像什麼(屬性)以及他(主要是「他」)可以執行什麼技巧(方法),以及他可以製作他的魔術技巧的什麼類型的東西(類型聲明)。因此,從這個魔術師的「公開」海報(頭文件)中,我可以理解他可以執行什麼樣的魔法以及他正在使用什麼道具。也許還有一個提到,這個特殊的魔術師已經從偉大的胡迪尼(階級遺產和胡迪尼因此成爲超級階級)學到了他的一些技巧。

如果我被允許在後臺,那麼我將能夠真正看到他是如何做自己的技巧的,也就是說,我可以在魔術師執行文件中查看。

這個比喻會有點沿着你如何理解自定義類的概念?

但是,我還沒有弄清楚類方法和實例方法的概念是如何與這個隱喻相關的?

你可以說實例方法屬於魔術師的這個特殊「實例」在這個特殊節目中表演的一類技巧,並且類方法將是當代魔術師可以執行的技巧嗎?第三,方法使用「類型」的方式有點混亂。有些似乎在界面文件中被預先聲明,有些似乎只是在方法中被動態地「聲明」?

要使用「魔術師」類舉一個例子,我的頭文件的理解可能是這樣的:

@interface Magician : NSHoudini 

// Instance method that given a variable of type rat it will turn this into something of type rabit 

- (rabit) FromRatToRabit: (rat) aRat; 

@end 

和實現文件可能是這樣的:

#import 「Magician.h」 

@implementation Magician 

rabit aRabit 
// rabit being the type and aRabit the variable 


- (rabit) FromRatToRabit:(rat)aRat; 
{ 

// some magic code goes here which will take what’s in the aRat variable, of type rat 
// and turn it into a form of type rabit and return it in the aRabit variable 

aRabit 
} 
@end 

如果上面是正確的我想知道爲什麼你「喂」的方法與aRat變量沒有聲明?或者當您在方法描述中使用該聲明時認爲該聲明已完成?

回答

0

這是理解公共接口與隱藏實現之間鴻溝的一個很好的比喻。但是我認爲你可能會有點被包裹在裏面,而且我確實看到了兩個主要的誤解 - 「Houdini」是超類,而類方法是「所有技巧」。

評估繼承層次結構敏感性的常見教科書方法是評估子類實例是否爲「超類實例」。這在現實中可能會變得非常抽象,但如果你設計了魔術師協會的醫療保險福利處理軟件或其他東西,在這種情況下,魔術師「是」絕對不是Houdini的東西!說他們都是自由職業者,所以每個魔術師都是「1099承包商」(自營職業收入的美國納稅表),或類似的東西。另一種思考的方式是認爲魔術師「是一個」舞臺表演者,「是一個」藝人,等等。並不是說你總是想製作這樣的軟件,但它可以幫助學習我想的概念。

你說你掙扎的第二件事是如何思考類方​​法。考慮類方法的行爲和類型固有的信息,並且獨立於任何實例。回到福利軟件的例子,可以說所有魔術師公會成員都得到一個401k(另一個美國稅務代碼事物,退休金賬戶),每個薪水支付$ X定義的貢獻。現在假設這不會隨着資歷的變化而變化,這將是保持在課堂水平上的一個很好的信息。所以,魔術師可以執行的所有技巧都不是階級方法 - 魔術師執行它們,因此它們將是實例方法。也許一個被禁止的技巧列表(因爲太危險了)可能是一個階級方法 - 這是一個作爲魔術師固有的規則,但是獨立於任何一個魔術師。最後,關於類型的第三個問題,我可以猜你在問什麼,但不確定。說你有一個方法

- (void)myMethod:(id)myArgument 
{ 
    NSLog(@"myArgument = %@",myArgument); 
} 

然後你要問哪裏myArgument聲明?它在方法簽名中被聲明,它是方法的一個參數,您可以在方法體的範圍內(大括號內)引用它。不知道這是不是你的意思。恐怕您必須提供一些實際的源代碼,而不是僞代碼,並指出您想知道的特定位置。

關於術語的一些小問題,抱歉,這會變得如此漫長 - 爲某個方法「饋送」一個值的術語通常是「傳遞」作爲「參數」或「參數」。 「描述」方法通常稱爲方法簽名或聲明,有時候我會聽到原型。是的,請澄清你在談論什麼類型,類型聲明等,我不是100%清楚你的問題。

希望這會有所幫助!

+0

非常感謝Carl,在這麼長的時間裏解釋這個!是的,我同意隱喻在理解一個概念時是危險的東西,但是通過上面給出的調整,我認爲我仍然可以以某種方式使用它。正如迪馬指出的那樣,Houdini作爲超級人選的選擇並不是很好。 – DAWO

+0

不客氣,很高興它對你有用。 –

2

你的比喻是可以接受的。頭文件是其他文件的接口,用於查看哪些文件告訴他們該文件及其相應的實現文件(如果有的話)可以訪問哪些文件。

我注意到你的代碼中雖然那個魔術師是一個子類Houdini。我可能會誤解你的例子,但就繼承而言,這可能是不正確的。你所說的每一個魔術師都是一種胡迪尼。應該說,霍迪尼是一種魔術師。

類VS實例已經解釋了很多次,不是特定於目標C,所以我不會進入太多。 Here is a post with some good answers。基本上,一個類函數/變量屬於類本身,並不特定於該類的任何實例。類函數/變量的另一個詞是static函數或變量。

不知道你的最後一個問題是什麼意思。目標c中的每個指針/變量都有一個類型。 你的語法雖然搞砸了,這裏是你的代碼貼出或許應該像(是的,我糾正兔:-P的拼寫)

@interface Houdini : Magician 

// Instance method that given a variable of type rat it will turn this into something of type rabit 

- (Rabbit *) FromRatToRabit: (Rat *) aRat; 

@end 

#import 「Houdini.h」 

@implementation Houdini 

Rabbit *aRabbit; // this is an ivar, although you're not actually using it anywhere, I'm just correcting your syntax 


- (Rabbit *) fromRatToRabit:(Rat *)aRat; 
{ 

// some magic code goes here which will take what’s in the aRat variable, of type rat 
// and turn it into a form of type rabit and return it in the aRabit variable 

    [aRat doSomethingToReturnRabbit]; // assuming rat has an instance function that returns a rabbit 
} 
@end 

你可以使用此功能通過做類似

Houdini *myHoudini = [[Houdini alloc] init]; 
Rat *houdinisRat = [[Rat alloc] init]; 
Rabbit *houdinisRabbit = [myHoudini fromRatToRabbit:houdinisRat]; 

請注意,這取決於有一個老鼠類和拉卜卜它的類(你沒有提供)。我也只是使用通常默認的初始化器。

希望這會有所幫助,您應該嘗試單獨搜索有關您有任何疑問的特定主題,因爲有大量的可用閱讀。

+0

謝謝迪瑪!是的,「胡迪尼」這個比喻有點不對,我現在可以看到。 – DAWO