2015-09-23 111 views
6

我正在面对有关协议方法调度的问题。Swift 2.0协议扩展方法调度

我有一个类层次结构,看起来就像是:

protocol E { 
    func test() 
} 

extension E { 
    func test() { 
     print("jello") 
    } 
} 

class A: E { 

} 

class B: A { 
    func test() { 
     print("hello") 
    } 
} 

但是,当我打电话testB类的实例静态被迫键入A,“爽”被打印出来,而不是“你好”。

let b: A = B() // prints "jello" not "hello" 
b.test() 

我的理解是test方法印刷“果冻”获取“集成”到的A实例(因为A符合E协议)。然后,我在B(继承A的形式)内提供test的另一个实现。我认为多态性将在此处起作用,并且在B上调用test实例存储在A引用将打印hello。这里发生了什么事?

不使用任何协议时,它的工作完美:

class A { 
    func test() { 
     print("jello") 
    } 
} 

class B: A { 
    override func test() { 
     print("hello") 
    } 
} 

let b: A = B() // prints "hello" 
b.test() 

什么是通过一项协议,增加了新的方法,以我的父类和子类中提供了一个新的实现,不必直接写这个方法在不同的父类,然后在子类中重写它?

你们有什么解决方法吗?

+0

不是你看到的确切行为,但密切相关:http://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future –

回答

3

闻起来像一个错误。

我想出的唯一解决方法是很丑陋......

protocol E { 
    func test() 
} 

func E_test(_s: E) { 
    print("jello") 
} 

extension E { 
    func test() { E_test(self) } 
} 

class A: E { 
    func test() { E_test(self) } 
} 

class B: A { 
    override func test() { 
     print("hello") 
    } 
} 

let b: A = B() 
b.test() 
+0

这确实是一个解决方案,但非常丑陋:)会提交一个雷达来确认。 –

+0

这不是一个错误,它的预期行为。尽管如此,我现在也在为这个问题而奋斗:) – manmal

+0

@manmal如果苹果希望这样做,但所有的程序员都觉得这是违反直觉的,并最终导致黑客入侵,那么我认为它可以归类为一个bug。 – mogelbuster