Objective-C中的@interface和@implementation

Objective-C中的@interface和@implementation

前言

Objc的类声明使用 interface ,但是在其它面向对象的语言中使用 class 来表示,interface 在 Java 中近似于 Objc 中的 protocol, 所以 Objc 中的 interface 以及 implementation 的设计思想是什么呢?

@interface

引用一段官方的解释

This information goes into the interface for your class—it defines the way you intend other objects to interact with instances of your class. The public interface is described separately from the internal behavior of your class, which makes up the class implementation. In Objective-C, the interface and implementation are usually placed in separate files so that you only need to make the interface public.

大概意思就是它定义了你希望与其它对象和类实例进行交互的方式,也就是 interface 只存在于能相互影响的两者间

那么问题来了 @interface 生成了 class?

刚接触 Objc 时肯定是从怎么写一个类开始的,在 .h 文件中写 @interface 声明类,然后在 .m 文件中写 @implementation,所以自然就会觉得是 @interface 就相当于 java 或者 C# 中写一个 class

Talk is cheap. Show me the code

Dog 类中只有 .m 文件只写 @implementation,在 Cat 类中只有 .h 文件只写 @interface

1
2
3
4
5
6
7
8
@implementation Dog : NSObject

@end

@interface Cat : NSObject

@end

验证

1
2
3
4
5
Class dogClass = NSClassFromString(@"Dog");
Class catClass = NSClassFromString(@"Cat");

NSLog(@"Dog: %@", dogClass);
NSLog(@"Cat: %@", catClass);

运行结果:

1
2
$ Dog: Dog
$ Cat: (null)

这个结果说明是 @implementation 生成了 class

@interface和@implementation

@interface 对类结构的合成没有决定性的作用, 只是没有它会丢失一些类自身的原始数据,如属性列表和协议列表,对对象消息发送并没有影响,所以 @interface 就是为了给调用者看,暴露自己的公有方法和属性等,是一个升级版的 protocol

@interface和@protocol

@interface@protocal 间唯一的区别就是是否和一个类型绑定

比如我们常常定义一个代理 id<XXDelegate> delegate 我们就不用知道这个代理到底是什么类型的,只用知道它能干什么就好了,同样可以这样定义 XXDelegate *delegate, 这样就会耦合一个 XXDelegate 类型,我们并不需要关心它是什么

一个问题

当子类需要使用父类的一个私有属性(方法)时,需要把这个属性(方法)放到父类的header中,但暴露给子类的同时暴露给了外部调用者,如何解决?

建立一个私有header,使用类扩展定义父类需要暴露给子类的属性(方法),然后在各自的 .m 文件中引用,如:

Father 类和 Son 类,继承关系,可以考虑建一个如 FatherPrivate.h 的私有header:

1
2
3
4
5
// FatherPrivate.h
@interface Father ()
@property (nonatomic, copy) NSString *privateThingSonNeed;
- (void)privateMethodNeedsSonOverride;
@end

同时在 Father.mSon.m 中同时 import 这个私有header,这样 FatherSon 内部对于定义的属性和方法都是透明的,而对外部是隐藏的(因为两个类的header中都没有 import 这个私有header)

top