示例:
游乐场:github
protocol A: class {}
extension A {
func someFunc() {
print("1")
}
}
class B {
weak var delegate: A?
func someTrigger() {
delegate?.someFunc()
}
}
class C: A {
lazy var b: B = {
let b = B()
b.delegate = self
return b
}()
func someFunc() {
print("2")
}
init() {
b.someTrigger()
}
}
let c = C()
/// printed 1
问题
在上面你可以看到一个例子来更好地理解这个问题。所以问题是:协议可以用实现者(实现协议的类(定义的函数来扩展吗?在我看来,示例代码的结果是出乎意料的。是否可以在没有协议继承的情况下以某种方式完成?
更新
我无法在协议A
中实现someFunc()
(它是UIKit
协议(。这就是为什么我考虑恰恰这种体系结构/配置。
protocol A: class {
func someFunc()
}
extension A {
func someFunc() {
print("1")
}
}
class AA: A { }
现在在AA类中,您可以使用默认实现(在扩展中(,也可以用自定义实现覆盖它。因此,您必须在协议本身中定义一个函数,因为它是接口。
但不在协议中定义它是没有意义的,这只是一个糟糕的设计,因为protocol=类上的接口。如果你想使用函数someFunc()
,你可以立即执行,而不需要重新定义它,因为自从你实现了一个协议以来,它就已经在那里了。
考虑在不暴露协议本身函数的情况下扩展协议,就像扩展要在其中实现该协议的类一样。
更新:
protocol MyProtocol: class {
func myFunc()
}
extension MyProtocol where Self: UIKitProtocol {
func myFunc() {
}
}
class AA: UIKitProtocol, MyProtocol { }
定义您自己的协议
经过我刚才尝试的一些测试,您必须在A
协议声明中公开someFunc()
函数,才能像这样调用C
类的someFunc()
函数:
protocol A: class {
func someFunc()
}
然后你会得到以下结果:
let c = C()
/// printed 2
更新:您可以创建另一个实现A
协议的类,并将其用于默认的someFunc()
实现,而不是向协议A
添加扩展:
class D: A {
func someFunc() {
print("1")
}
}
class B {
weak var delegate: D?
func someTrigger() {
delegate?.someFunc()
}
}
class C: D {
lazy var b: B = {
let b = B()
b.delegate = self
return b
}()
override func someFunc() {
print("2")
}
override init() {
super.init()
b.someTrigger()
}
}
这也会有你预期的结果。