swift - 转换为协议时未调用协议扩展方法
问题描述
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 & B 实例即使在强制转换为时也总是调用具体方法,但是如果我在实例上StateManager
定义扩展方法,为什么结果会有所不同?是否会被强制转换为从而切断for &的最具体版本? StateManager
StateMachine
Self
StateManager
predicate()
StateMachine<Int, Int, Int>
StateMachine<String, String, String>
基本上我希望StateMachine<Int, Int, Int>
&StateMachine<String, String, String>
泛型类型有自己的实现,predicate()
当我将任一泛型类型转换为 时StateManager
,我希望predicate()
泛型类型上执行(不是默认StateManager
实现。结果应该与predicate()
通过转换A
&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)
有没有办法做到这一点,或者我不能为此使用协议扩展方法?