访问控制和 protected


翻译:老码团队翻译组-Arya 校对:老码团队翻译组-Jame

原文再续,书折第一回。

很多其他编程语言都有一种”protected“设定,可以限制某些类方法只能被它的子类所使用。

Swift 支持了访问控制后,大家给我们的反馈都很不错。而有的开发者问我们:“为什么 Swift 没有类似 protected 的选项?”

当我们在设计 Swift 访问控制的不同等级时,我们认为有两种主要场景:

  • 在一个 APP 里:隐藏某个类的私密细节。
  • 在一个开源框架里:不让导入这个框架的 APP,随便接触框架的内部实现细节。

上面的两种常见情况,对应着 private 和 internal 这两个等级。

而 protected 相当于把访问控制和继承特性混在一起,把访问控制的等级设定增加了一个维度,使之复杂化。即使设定了 protected,子类还是可以通过新的公开方法、新的属性来接触到所谓“protected”了的 API。另一方面,我们可以在各种地方重写一个方法,所谓的保护却没有提供优化机制。这种设定往往在做不必要的限制 一 protected 允许了子类,但又禁止所有其他别的类(包括那些帮助子类实现某些功能的类)接触父类的成员。

有的开发者指出,apple 的框架有时候也会把给子类用的 API 分隔出来。这时候 protected 不就有用了吗?我们研究后发现,这些方法一般属于下面两种情况:一是这些方法对子类以外的类没啥用,所以不需要严格保护(例如上面说的协助实现某些功能的类)。二是这些方法就是设计出来被重写,而不是直接用的。举个例子,drawRect(_:) 就是在 UIKit 基础上使用的方法,但它不能在 UIKit 以外应用。

除此之外,如果有了 protected,它要怎么样和 extension 相互作用呢?一个类的 extension 能接触它的 protected 成员吗?一个子类的 extension 可以接触父类的 protected 成员吗?extension 声明的位置对访问控制等级有没有影响呢?(复杂到要哭了是不是?)

对访问控制的设计,也依循了 Objective-C 开发者(包括 apple 内外的)的常规做法。Objective-C 方法和属性一般在.h 头文件里声明,但也可以写在.m 实现文件里。假如有一个公开的类,想把里面某些部分设为只有框架内可以获取时,开发者一般会创建另一个头文件给内部使用。以上三种访问级别,就对应了 Swift 里面的 public,private 和 internal。

Swift 的访问控制等级和继承无关,是单维度、非常清楚明了的。我们认为这样的模式更简洁,同时满足了最主要的需求:将一个类、或一个框架的实现细节隔离保护起来。这可能和你以前用过的不同,但我们鼓励你试试看。


本章节不是老码的原创,是老码认真的阅读了苹果的官方博客,自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌。还是看不懂?请到老码官方微博咆哮。

本文由翻译自 Apple Swift Blog :Access Control and Protected

书籍推荐