2010-06-14 74 views
4

我剛進入Objective-C(Java是我的主要OO語言)。爲什麼在接口中聲明Objective-C實例變量?

定義對象的實例變量的接口,而不是類似乎有些奇怪。我習慣於一個接口是一個公共的API定義,除了方法簽名之外沒有任何東西(這裏不包括常量)。

是有一些原因,狀態接口中定義的(即使是私有的)和行爲是在類中定義。看起來很奇怪,因爲對象是狀態+行爲,所以定義會被分成兩個獨立的地方。

它是一個設計的好處是某種方式?在Objective-C中你只是被迫處理的後期問題中的痛苦?一個非問題,只是不同?關於爲什麼這樣做的背景?

或者你可以把一個類的對象狀態,我只是還沒有打在我的書的部分呢?

回答

12

UPDATE

以下是聲明在實施實例變量的語言功能之前寫的答案被實施。問題的前提現在不再有效。正如FireLizzard所說,沒有必要去@interface,你不想公開。


這是一個事實,即Objective-C的起源是建立在C.的C方式頂部相當薄層宿醉是定義的接口模塊(不與Java interface混淆)在一個頭文件並將其包含在每個編譯單元中。這類似於將聲明自動複製粘貼到每個編譯文件的頂部。如果這看起來很原始,那是因爲它是,但C是40歲的語言。

你必須定義實例變量 - 在接口,因爲Objective-C對象作爲C結構,它們本身只是內存塊和塊內名爲偏移實現 - 甚至是私人的。代表每個類的對象的結構必須包含用於超類實例變量的空間,以便子類至少需要知道表示超類的C結構的大小以及公共和受保護的實例變量偏移量。不幸的是,這意味着所有的實例變量,甚至私有的變量都必須作爲外部接口的一部分公開。* C++的另一個OO版本由於相同的原因而遭受同樣的問題。

這有點痛苦,必須記下所有方法簽名兩次,但你已經習慣了。

*使用64位運行時,您不再需要聲明實例變量在@interface合成訪問器,但由於所有的方法都是公開的,這仍然意味着暴露內部狀態到外面的世界,althoug它確實緩解fragile base class問題。

+1

imo,這是正確的答案,因爲它實際上回答了這個問題:Why - kudos和一個贊成Jeremy – Rhubarb 2011-08-26 18:16:47

+1

隨着Objective-C 2.0,你不再需要在'@ interface'中聲明_anything_。在.m文件中聲明擴展中的私有方法和屬性('@interface MyClassName()')。當然,您可以通過運行時找到這些方法和屬性定義,但這與Java的大部分反射沒有什麼不同。 – 2013-11-22 05:49:33

+0

該功能實施之前的答案日期。我已經添加了一個註釋來說明這一點。 – JeremyP 2013-11-22 14:26:38

7

在Objective C接口都

布拉德·考克斯是誰設計目標C決定的C聲明和定義等同應該明確不參考實例,以便每個類都有一個@接口部分,告訴它什麼看起來像外部和@implementation說明它是如何實現的。

的Java後來一起,改變了對象模型,以便有隻有一個拉@interface和@implementation一起對象的定義。編譯器(和運行時自檢)實際上構造了代碼中的接口。

在Java中的接口相對應的是在Objective C.

議定書你只是習慣了它。

+0

並且Gosling直接從Objective-C派生Java,增加了「接口」來有效地表示「抽象類」.... – bbum 2010-06-14 22:00:16