2015-09-23 19 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") 
    } 
} 

しかし、私は静的Aを入力することを余儀なくクラスBのインスタンスにtestを呼び出すとき、「ゼリー」「こんにちは」ではなく、印刷されますが。

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

私の理解は、testメソッド印刷が「ゼリー」(AEプロトコルに準拠するため)Aのインスタンスに「統合」されることをです。次にtestの別の実装をB(これはフォームAを継承しています)内に提供します。多形性はここではうまくいくと思って、A参照内に格納されているBtestインスタンスを呼び出すと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もしAppleがこれを意図していたとしても、すべてのプログラマーは直観に反してハッキングしてしまいました。 – mogelbuster

関連する問題