继承树中的调用协议默认实现
Call protocol default implementation in inherence tree
这是一个非常相似的问题:,但是 none 的答案涵盖了 继承发挥作用 的情况。答案建议将其转换为协议类型本身将解决它,但在这种情况下不会(在操场上复制粘贴):
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 的默认实现?
编辑:我的用例如下:
我有一个被 class 采纳的协议,它经常被 subclass 编辑。该协议有多个默认方法,可以相互调用。一些 subclasses 需要覆盖方法,做一些事情,并调用 super.method()
(最终调用协议的默认实现,因为 superclass 可能已经覆盖了协议默认实现也是如此)。所以我真的需要动态调度。
尽管协议支持使用扩展的具体实现,但这违背了 protocol
的概念
A protocol defines a blueprint of methods, properties, and other
requirements that suit a particular task or piece of functionality.
在您真正确定这不会是 overriden
.
之前,应尽可能避免它
解决方案一:
如果您遇到过上述情况,那么我建议引入一个中介 class
,它除了符合 protocol
之外什么都不做,然后从 subClasses
继承 subClasses
15=]。
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()
将打印以下输出,
Hi from 2
Hi, I am protocol
Cheese from protocol
方案二:
如另一个 中所述,从 protocol
中删除 sayCheese
方法,这样您的协议声明将为空,但 sayCheese
将保留在 extension
并且它会中断对 sayCheese
的递归调用,从而使您的应用不会冻结。
public protocol MyProtocol {}
这是一个非常相似的问题:
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 的默认实现?
编辑:我的用例如下:
我有一个被 class 采纳的协议,它经常被 subclass 编辑。该协议有多个默认方法,可以相互调用。一些 subclasses 需要覆盖方法,做一些事情,并调用 super.method()
(最终调用协议的默认实现,因为 superclass 可能已经覆盖了协议默认实现也是如此)。所以我真的需要动态调度。
尽管协议支持使用扩展的具体实现,但这违背了 protocol
A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality.
在您真正确定这不会是 overriden
.
解决方案一:
如果您遇到过上述情况,那么我建议引入一个中介 class
,它除了符合 protocol
之外什么都不做,然后从 subClasses
继承 subClasses
15=]。
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()
将打印以下输出,
Hi from 2
Hi, I am protocol
Cheese from protocol
方案二:
如另一个 protocol
中删除 sayCheese
方法,这样您的协议声明将为空,但 sayCheese
将保留在 extension
并且它会中断对 sayCheese
的递归调用,从而使您的应用不会冻结。
public protocol MyProtocol {}