This question already has an answer here:
Implement protocol through extension [duplicate]

(1个答案)


4年前关闭。




我正在尝试从协议扩展中覆盖实例方法,但遇到了一些麻烦。

对于上下文,我正在制作一个具有很多不同UICollectionViews的iOS应用。这些视图从不同的数据库中获取数据(需要不同的回调函数),并且具有非常不同的布局。因为(数据库,布局)的任何组合都是可能的,所以没有大量代码重复就很难形成一个很好的OOP类层次结构。

我的想法是将布局功能(通常是在UICollectionViewDelegateFlowLayout协议中定义的布局功能)放入协议扩展中,因此我可以使用扩展为实现所有相关布局功能的协议来装饰给定的UICollectionView子类,但是我很难它的。问题的实质包含在下面的代码中。
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"

有什么想法吗?

最佳答案

仅当符合这些协议的类未实现该方法本身时,才调用协议中的默认实现。类的方法将覆盖协议的默认实现,而不是相反。

通常,您会执行以下操作:

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继承子类,请放心。但是关键是协议默认实现不会覆盖类的实现,而是相反。

关于ios - 如何在Swift中的协议(protocol)扩展中覆盖实例方法? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38600722/

10-16 04:50