类是否可以在协议的扩展上显式调用方法?

时间:2017-04-11 19:14:41

标签: ios swift

假设存在以下协议,其扩展名提供了someFuncWithDefaultImplementation()的默认实现。

那么MyClass2是否可以提供自己的someFuncWithDefaultImplementation()实现,它还从扩展中调用该方法的默认实现?

protocol MyProtocol : class {
    func someFuncWithDefaultImplementation()
    func someFunc()
    var  someInt:Int { get set }
}

extension MyProtocol {
    func someFuncWithDefaultImplementation() {
        someInt = 5
    }

    func someFunc() {
        someFuncWithDefaultImplementation()
    }
}

class MyClass :  MyProtocol {
    var someInt = 6
}

class MyClass2 : MyProtocol
{
    var someInt: Int = 4
    func someFuncWithDefaultImplementation()
    {
        // do some additional stuff
         /*** someFuncWithDefaultImplementation()  invoke MyProtocol extension implementation here ***/
    }
}


    let class1 = MyClass()
    class1.someFunc()

    let class2 = MyClass2()
    class2.someFunc()

2 个答案:

答案 0 :(得分:1)

帖子中的following answer

描述了使用嵌套的虚拟类型从已经提供了自己的蓝色打印方法实现的类型中访问协议的默认实现。我们可以扩展此方法以允许实际使用MyClass2实例的(blueprinted)属性,但是在MyClass2已经实现其自定义版本的默认实现的调用内(因此优先于默认的一个)。

我们首先看一下示例稍微轻一点的版本,并为someFuncWithDefaultImplementation()提供默认实现

protocol MyProtocol : class {
    func someFuncWithDefaultImplementation()
    var someInt: Int { get set }
}

extension MyProtocol {
    func someFuncWithDefaultImplementation() {
        print("Called default impl. Currently, someInt = \(someInt)")
        print("Mutates someInt from within default implementation (0) ...")
        someInt = 0
    }
}

我们在someFuncWithDefaultImplementation() MyClass2的自定义实现中使用非优雅的嵌套类型解决方案来调用后者的默认实现,但在Dummy实例中存储引用返回MyClass2实例,允许someInt MyClass2属性在默认实现调用中使用(用于读写),即使从{{1输入。

Dummy

您也可以选择在函数外部声明嵌套class MyClass2 : MyProtocol { var someInt: Int = 42 func someFuncWithDefaultImplementation() { // do some additional stuff ... print("In MyClass2 implementation, currently someInt = \(someInt)") /* Dummy 'MyClass2'-capturing type used to call the default implementation of 'MyProtocol', but with read and write access to 'MyClass2':s self:s 'someInt' instance. */ class Dummy : MyProtocol { unowned let myClass2: MyClass2 init(_ myClass2: MyClass2) { self.myClass2 = myClass2 } var someInt: Int { get { return myClass2.someInt } set { myClass2.someInt = newValue } } } // call default implementation of 'someFuncWithDefaultImplementation' // supplying 'self' to read/write access to self.someInt. Dummy(self).someFuncWithDefaultImplementation() print("Back in MyClass2:s implementation; now someInt = \(someInt)") // 0, woah, mutated in default implementation! } } let a = MyClass2() a.someFuncWithDefaultImplementation() /* In MyClass2 implementation, currently someInt = 42 Called default impl. Currently, someInt = 42 Mutates someInt from within default implementation (0) ... Back in MyClass2:s implementation; now someInt = 0 */ ,只需将其标记为Dummy,以确保无法从外部private访问它:

MyClass2
然而,我将重复与链接答案的作者相同:这种方法不是很优雅。

答案 1 :(得分:-1)

仅在您进行子类化时,请参阅:

import Foundation

protocol MyProtocol : class {
    func someFuncWithDefaultImplementation()
    func someFunc()
    var  someInt:Int { get set }
}

extension MyProtocol {
    func someFuncWithDefaultImplementation() {
        someInt = 5
        print("a")
    }

    func someFunc() {
        someFuncWithDefaultImplementation()
    }
}

class MyClass :  MyProtocol {
    var someInt = 6
}

class BaseClass: MyProtocol {
    var someInt: Int = 4
}
class MyClass2 : BaseClass
{

    func someFuncWithDefaultImplementation()
    {
        // do some additional stuff
        print("b")
        (self as BaseClass).someFuncWithDefaultImplementation()
    }
}

如果您在Playground中添加上述内容,然后致电:

MyClass2().someFuncWithDefaultImplementation()

打印:

b
a

您要求的是什么,请参见截图。

enter image description here