我想知道有没有一种方法可以用多态风格处理协议默认实现。示例
protocol RockInterface {
}
extension RockInterface {
func foo() {
print("You Rock")
}
}
extension RockInterface where Self: Metal {
func foo() {
print("Metal")
}
}
extension RockInterface where Self: Grunge {
func foo() {
print("Grunge")
}
}
class Rock: RockInterface {
init() {
foo()
}
}
class Metal: Rock {
}
class Grunge: Rock {
}
let rock = Rock() //prints "You Rock"
let metal = Metal() //prints "You Rock"
let grunge = Grunge() //prints "You Rock"
我期望Metal()打印"Metal",Grunge打印"Grunge"。但默认实现似乎是在编译时而不是运行时解决的。我的假设是对的还是错的?我怎样才能得到预期的行为?
至少有两个因素会对您看到的行为产生影响,有些在您的控制范围内,有些则不在。
- 不属于协议要求的函数是静态调度的。如果您想要动态调度,那么您需要将该方法添加到协议声明中:
protocol RockInterface {
func foo()
}
- 然而,以上内容并不能解决您的问题,因为子类继承父类的协议见证表。请参阅此优秀答案以了解更多详细信息
我还认为您的设计是一个很好的设计,因为您将协议和符合该协议的类紧密耦合。如果你真的需要你描述的行为,那么一个解决方案是删除协议扩展,并在每个类中实现foo
方法:
protocol RockInterface {
func foo()
}
class Rock: RockInterface {
init() {
foo()
}
func foo() {
print("You Rock")
}
}
class Metal: Rock {
override func foo() {
print("Metal")
}
}
class Grunge: Rock {
override func foo() {
print("Grunge")
}
}
let rock = Rock() //prints "You Rock"
let metal = Metal() //prints "Metal"
let grunge = Grunge() //prints "Grunge"