转换为协议时不调用协议扩展方法

时间:2018-06-14 07:02:03

标签: swift protocols

protocol StateManager : class {
    func predicate(filterTag: String?) -> NSPredicate?
}

extension StateManager {
    func predicate(filterTag: String?) -> NSPredicate?
    {
        print("StateManager.predicate(\(filterTag!))")
        return nil
    }
}

class StateMachine<T, S, E> : StateManager {
}

class A : StateManager {
    func predicate(filterTag: String?) -> NSPredicate?
    {
        print("concrete A.predicate(\(filterTag!))")
        return NSPredicate(value: true)
    }
}

class B : StateManager {
    func predicate(filterTag: String?) -> NSPredicate?
    {
        print("concrete B.predicate(\(filterTag!))")
        return NSPredicate(value: false)
    }
}

extension StateManager where Self : StateMachine<String, String, String> {
    //FIXME: Refactor to use an enum vs. String?
    func predicate(filterTag: String?) -> NSPredicate?
    {
        print("StateMachine<String, String, String>.predicate(\(filterTag!))")
        return NSPredicate(value: true)
    }
}

extension StateManager where Self : StateMachine<Int, Int, Int> {
    //FIXME: Refactor to use an enum vs. String?
    func predicate(filterTag: String?) -> NSPredicate?
    {
        print("StateMachine<Int, Int, Int>.predicate(\(filterTag!))")
        return NSPredicate(value: false)
    }
}

example("Call via concrete type") {
    let intState: StateMachine<Int, Int, Int> = StateMachine<Int, Int, Int>()
    let strState: StateMachine<String, String, String> = StateMachine<String, String, String>()
    let a: A = A()
    let b: B = B()

    intState.predicate(filterTag: "intState")
    strState.predicate(filterTag: "strState")
    a.predicate(filterTag: "A")
    b.predicate(filterTag: "B")
}

example("Call via protocol type") {
    let intState: StateMachine<Int, Int, Int> = StateMachine<Int, Int, Int>()
    let strState: StateMachine<String, String, String> = StateMachine<String, String, String>()
    let a: A = A()
    let b: B = B()

    let intProtocol = intState as StateManager
    let strProtocol = strState as StateManager
    intProtocol.predicate(filterTag: "intProtocol")
    strProtocol.predicate(filterTag: "strProtocol")

    let aProtocol = a as StateManager
    let bProtocol = b as StateManager
    aProtocol.predicate(filterTag: "aProtocol")
    bProtocol.predicate(filterTag: "bProtocol")
}

输出

--- Call via concrete type example ---
StateMachine<Int, Int, Int>.predicate(intState)
StateMachine<String, String, String>.predicate(strState)
concrete A.predicate(A)
concrete B.predicate(B)

--- Call via protocol type example ---
StateManager.predicate(intProtocol)
StateManager.predicate(strProtocol)
concrete A.predicate(aProtocol)
concrete B.predicate(bProtocol)

我明白为什么A&amp; B实例总是在转换为StateManager时调用具体方法,但如果我在StateManager实例上定义StateMachine的扩展方法,为什么结果会有所不同? Self是否会被StateManager转换为predicate()&amp; StateMachine<Int, Int, Int>的最具体版本StateMachine<String, String, String> StateMachine<Int, Int, Int>

基本上我想要StateMachine<String, String, String>&amp; predicate()泛型类型具有自己的StateManager实现,当我将泛型类型转换为predicate()时,我希望执行泛型类型的StateManager(不是默认值) predicate()实施。结果应与通过将A&amp; B类投射到StateManager

来执行--- Call via protocol type example --- (StateMachine<Int, Int, Int> as StateManager).predicate() -calls-> StateMachine<Int, Int, Int>.predicate(intState) (StateMachine<String, String, String> as StateManager).predicate() -calls-> StateMachine<String, String, String>.predicate(strState) concrete A.predicate(aProtocol) concrete B.predicate(bProtocol) 相同
{{1}}

有没有办法做到这一点,或者我不能使用协议扩展方法吗?

0 个答案:

没有答案