Swift协议可以通过向函数和计算属性添加扩展来提供默认实现。我做了很多次。我的理解是,默认实现仅用作“后备”:它在类型符合协议但未提供自己的实现时执行。使用协议中定义的默认参数实现函数
至少这是我怎么会看The Swift Programming Language指南:
如果符合的类型提供了自己的实现所需的方法或属性,即实现将被用来代替扩展提供了一个。
现在我跑到哪里实现我的自定义类型某个协议确实提供特定功能的实施情况,但它不执行 - 而执行的协议扩展定义的实现。
作为一个例子,我定义一个协议Movable
具有功能move(to:)
并提供此功能的默认的实现的扩展:
protocol Movable {
func move(to point: CGPoint)
}
extension Movable {
func move(to point: CGPoint = CGPoint(x: 0, y: 0)) {
print("Moving to origin: \(point)")
}
}
接下来,我定义一个Car
类符合Movable
,但为move(to:)
函数提供了自己的实现:
class Car: Movable {
func move(to point: CGPoint = CGPoint(x: 0, y: 0)) {
print("Moving to point: \(point)")
}
}
现在我创建一个新的Car
丧气它作为一个Movable
:
let castedCar = Car() as Movable
取决于我是否通过值可选参数point
我观察到两种截然不同的行为:
当通过点为可选参数
→的
Car
的实现被称为:castedCar.move(to: CGPoint(x: 20, y: 10))
输出:
移至点:(20.0,10。0)
当我调用
move()
功能而无需为可选参数提供值的Car
的实现将被忽略并且→
Movable
协议的默认实现被调用,而不是:castedCar.move()
输出:
移动到原点:(0.0,0.0)
我相信编译时会添加默认值,因此必须使用该变量的静态类型。 – Sulthan
您正在将Car转换为Movable,因此它将调用Movable方法。如果您没有将汽车投入移动,它会调用您的汽车的移动方法 –
@LeoDabus:如果我没有将'汽车'移动到'移动',我不会遇到这个问题。然而,当我执行演员时出现问题的原因是我的问题的关键。在一个实际的面向协议的实现中,我不知道我正在处理的对象的实际类 - 我只知道它符合'Movable'协议。 'let castedCar = Car()as'Movable'这行就是模仿这种情况的一种手段,以保持示例代码的清洁。 – Mischa