如何从 Swift 中的协议扩展覆盖实例方法?
How to override instance method from protocol extension in Swift?
我正在尝试覆盖协议扩展中的实例方法,但遇到了一些麻烦。
对于上下文,我正在制作一个包含许多不同 UICollectionView 的 iOS 应用程序。这些视图从不同的数据库获取数据(需要不同的回调函数)并且具有非常不同的布局。因为(数据库、布局)的任何组合都是可能的,所以很难在没有大量代码重复的情况下制作一个漂亮的 OOP class 层次结构。
我想到了将布局函数(主要是那些在 UICollectionViewDelegateFlowLayout 协议中定义的函数)放入协议扩展中,这样我就可以用一个扩展的协议来装饰给定的 UICollectionView subclass 以实现所有相关布局功能,但我很难过。问题的实质包含在下面的代码中。
class Base {
func speak(){
print("Base")
}
}
class SubA: Base, ProtocolA {}
class SubB: Base, MyProtocolB {}
protocol MyProtocolA{
func speak()
}
protocol MyProtocolB{
func speak()
}
extension MyProtocolA{
func speak(){
print("A")
}
}
extension MyProtocolA{
func speak(){
print("B")
}
}
let suba = SubA()
suba.speak() // prints "Base", I want it to print "A"
let subb = SubB()
subb.speak() // prints "Base", I want it to print "B"
想法?
仅当符合这些协议的 class 本身未实现该方法时,才会调用协议中的默认实现。 classes 的方法会覆盖协议的默认实现,而不是相反。
通常,您会执行以下操作:
protocol MyProtocolA {
func speak()
}
protocol MyProtocolB {
func speak()
}
extension MyProtocolA {
func speak() {
print("A")
}
}
extension MyProtocolB {
func speak() {
print("B")
}
}
class SubA: MyProtocolA {}
class SubB: MyProtocolB {}
let suba = SubA()
suba.speak() // prints "A"
let subb = SubB()
subb.speak() // prints "B"
但如果你这样做
class SubC: MyProtocolA {
func speak (){
print("C")
}
}
let subc = SubC()
subc.speak() // prints "C"
坦率地说,正如您看到的那样,Base
的使用在此示例中完全多余,因此我将其删除。显然,如果您出于其他原因需要从 Base
中替换 class,请随意。但关键是协议默认实现不会覆盖 classes 的实现,而是相反。
我正在尝试覆盖协议扩展中的实例方法,但遇到了一些麻烦。
对于上下文,我正在制作一个包含许多不同 UICollectionView 的 iOS 应用程序。这些视图从不同的数据库获取数据(需要不同的回调函数)并且具有非常不同的布局。因为(数据库、布局)的任何组合都是可能的,所以很难在没有大量代码重复的情况下制作一个漂亮的 OOP class 层次结构。
我想到了将布局函数(主要是那些在 UICollectionViewDelegateFlowLayout 协议中定义的函数)放入协议扩展中,这样我就可以用一个扩展的协议来装饰给定的 UICollectionView subclass 以实现所有相关布局功能,但我很难过。问题的实质包含在下面的代码中。
class Base {
func speak(){
print("Base")
}
}
class SubA: Base, ProtocolA {}
class SubB: Base, MyProtocolB {}
protocol MyProtocolA{
func speak()
}
protocol MyProtocolB{
func speak()
}
extension MyProtocolA{
func speak(){
print("A")
}
}
extension MyProtocolA{
func speak(){
print("B")
}
}
let suba = SubA()
suba.speak() // prints "Base", I want it to print "A"
let subb = SubB()
subb.speak() // prints "Base", I want it to print "B"
想法?
仅当符合这些协议的 class 本身未实现该方法时,才会调用协议中的默认实现。 classes 的方法会覆盖协议的默认实现,而不是相反。
通常,您会执行以下操作:
protocol MyProtocolA {
func speak()
}
protocol MyProtocolB {
func speak()
}
extension MyProtocolA {
func speak() {
print("A")
}
}
extension MyProtocolB {
func speak() {
print("B")
}
}
class SubA: MyProtocolA {}
class SubB: MyProtocolB {}
let suba = SubA()
suba.speak() // prints "A"
let subb = SubB()
subb.speak() // prints "B"
但如果你这样做
class SubC: MyProtocolA {
func speak (){
print("C")
}
}
let subc = SubC()
subc.speak() // prints "C"
坦率地说,正如您看到的那样,Base
的使用在此示例中完全多余,因此我将其删除。显然,如果您出于其他原因需要从 Base
中替换 class,请随意。但关键是协议默认实现不会覆盖 classes 的实现,而是相反。