这是一个非常相似的问题:Calling protocol default implementation from regular method,但是当继承发挥作用时,所有答案都无法解决。答案建议将其强制转换为协议类型本身即可解决,但在这种情况下不可行(在操场上复制粘贴):
public protocol MyProtocol {
func sayCheese()
}
public extension MyProtocol {
func sayHi() {
print("Hi, I am protocol")
sayCheese()
}
func sayCheese() {
print("Cheese from protocol")
}
}
public class MyFirstClass: MyProtocol {
public func sayCheese() {
print("Cheese from 1")
(self as MyProtocol).sayCheese()
}
}
public class MySecondClass: MyFirstClass {
override init() {
super.init()
sayHi()
}
public func sayHi() {
print("Hi from 2")
super.sayHi()
}
public override func sayCheese() {
print("Said cheese from 2")
super.sayCheese()
}
}
MySecondClass()
它打印以下内容:
...
Said cheese from 2
Cheese from 1
Said cheese from 2
Cheese from 1
...
在MyFirstClass
的实例中,如何调用方法sayCheese
的MyProtocol的默认实现?
编辑:我的用例如下:
我有一个被类继承的协议,该协议被大量子类化。该协议有多个默认方法,可以互相调用。一些子类需要重写方法,执行操作并调用super.method()
(以最终调用协议的默认实现,因为超类也可能已重写协议的默认实现)。所以我真的需要动态调度。
答案 0 :(得分:1)
尽管协议支持使用扩展的具体实现,但这违背了protocol
的概念
协议定义了方法,属性和其他方法的蓝图 适合特定任务或功能的需求。
,在您完全确定这不是overriden
之前,应尽可能避免。
解决方案1:
如果您遇到了上述情况,那么我建议您介绍一个中介class
,除了遵循protocol
之外什么都不做,然后从{{1}那里继承subClasses
}。
class
现在创建对象public class Intermediary: MyProtocol {}
public class MyFirstClass: Intermediary {
public func sayCheese() {
print("Cheese from 1")
super.sayCheese()
}
}
public class MySecondClass: MyFirstClass {
override init() {
super.init()
sayHi()
}
public func sayHi() {
print("Hi from 2")
super.sayHi()
}
public override func sayCheese() {
print("Said cheese from 2")
super.sayCheese()
}
}
将打印以下输出,
MySecondClass()
解决方案2:
如其他question所述,请从Hi from 2
Hi, I am protocol
Cheese from protocol
中删除sayCheese
方法,以便您的协议声明为空,但protocol
将保留在sayCheese
中它将中断对extension
的递归调用,从而使您的应用不会冻结。
sayCheese