我已经看到了很多原因,为什么使用变量而不是函数来设计API是有问题的,对我来说,使用计算属性似乎是一种解决方法。有充分的理由将实例变量封装起来。在这里,我创建了Car遵循的汽车协议。该协议具有一个访问器方法,该方法返回一个机箱对象。由于Car符合它,所以RaceCar子类可以覆盖它并返回不同的Chassis子类。这使Car类可以编程到接口(汽车),而知道RacingChassis的RaceCar类可以直接访问_racingChassis变量。
class Chassis {}
class RacingChassis: Chassis {}
protocol Automobile {
func chassis() -> Chassis
}
class Car: Automobile {
private var _chassis: Chassis
init () {
_chassis = Chassis()
}
func chassis() -> Chassis {
return _chassis
}
}
class RaceCar: Car {
private var _racingChassis: RacingChassis
override init () {
_racingChassis = RacingChassis()
super.init()
}
override func chassis() -> Chassis {
return _racingChassis
}
}
为什么使用变量设计API会失败的另一个示例是协议中有变量时。如果您想将所有协议功能分解为扩展名,可以将存储的属性放入扩展名中,而必须在类中进行定义(要使其编译即可,您必须在代码中取消注释) AdaptableViewController类,并从扩展名中删除mode变量):
protocol Adaptable {
var mode: Int { get set }
func adapt()
}
class AdaptableViewController: UIViewController {
// var mode = 0
}
extension AdaptableViewController: Adaptable {
var mode = 0 // compiler error
func adapt() {
//TODO: add adapt code
}
}
上面的代码将出现此编译器错误:“扩展名可能没有存储的属性”。您可以按照以下方式重新编写上面的示例,以便可以使用函数代替扩展中的协议中的所有内容:
protocol Adaptable {
func mode() -> Int
func adapt()
}
class AdaptableViewController: UIViewController {
}
extension AdaptableViewController: Adaptable {
func mode() -> Int {
return 0
}
func adapt() {
// adapt code
}
}
strong
属性的Objective-C类,尝试覆盖它时遇到了错误-但似乎我错过了将其转换为“隐式展开的可选”(chassis!
) Swift,因此进行override var chassis : Chassis!
修复。