是在编译或运行时解决的swift扩展默认实现



我想知道有没有一种方法可以用多态风格处理协议默认实现。示例

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"。但默认实现似乎是在编译时而不是运行时解决的。我的假设是对的还是错的?我怎样才能得到预期的行为?

至少有两个因素会对您看到的行为产生影响,有些在您的控制范围内,有些则不在。

  1. 不属于协议要求的函数是静态调度的。如果您想要动态调度,那么您需要将该方法添加到协议声明中:
protocol RockInterface {
    func foo()
}
  1. 然而,以上内容并不能解决您的问题,因为子类继承父类的协议见证表。请参阅此优秀答案以了解更多详细信息

我还认为您的设计是一个很好的设计,因为您将协议和符合该协议的类紧密耦合。如果你真的需要你描述的行为,那么一个解决方案是删除协议扩展,并在每个类中实现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"

相关内容

  • 没有找到相关文章

最新更新