2010-06-14 77 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