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}}
有没有办法做到这一点,或者我不能使用协议扩展方法吗?