2017-01-28 12 views
0

クラスへの実装に制約のあるプロトコル拡張で定義されているデフォルトのメソッド実装にアクセスしようとしています。 '通常の'宣言はうまくいきますが、プロトコルにキャストしようとすると、その型はwhere句を満たしていますが、プロトコルのデフォルトの定義済みメソッドにアクセスすることはできません。制限付きプロトコルへのキャストがデフォルトメソッドにアクセスできない

この例を考えてみてください:

class Person { 

    var name: String 
    init(name: String) { 
     self.name = name 
    } 
} 

class Hero: Person { 

    var ability: String 
    init(name: String, ability: String) { 
     self.ability = ability 
     super.init(name: name) 
    } 
} 

class Pilot: Person { 

    var callSign: String 
    init(name: String, callSign: String) { 
     self.callSign = callSign 
     super.init(name: name) 
    } 
} 

class Programmer: Person { 
    var favoriteLanguage: String 
    init(name: String, favoriteLanguage: String) { 
     self.favoriteLanguage = favoriteLanguage 
     super.init(name: name) 
    } 
} 

// define a protocol 
protocol PersonPresenter: class { } 
// extend it where the conformer is a type of Person 
extension PersonPresenter where Self: Person { 

    func displayName() { 
     print(name.uppercased()) 
    } 
} 

// conform subclasses of Person to PersonPresenter 
extension Hero: PersonPresenter { } 
extension Pilot: PersonPresenter { } 
extension Programmer: PersonPresenter { } 

let myHero = Hero(name: "Hiro", ability: "Bend time & space") 
myHero.displayName() // prints 'HIRO' 

let myPilot = Pilot(name: "Pete", callSign: "Maverick") 
myPilot.displayName() // prints 'PETE' 

let myProgrammer = Programmer(name: "Chris", favoriteLanguage: "Swift") 
myProgrammer.displayName() // prints 'CHRS' 

let people: [Person] = [myHero,myPilot,myProgrammer] 

if let presenter = people[0] as? PersonPresenter { 
    presenter.displayName() // Errror, PerseonPresenter is not a subtype of 'Person' 
} 

場所の制約を満たしながら試すことを強制してアクセスする各特定のサブクラスにキャストしないように、私はPersonPresenterにキャストする方法を見つけるしたいと思いますプロトコル拡張のデフォルト実装。または、スーパークラス(他の多くの場所で使用される可能性があります)をプロトコルに準拠させる必要はありません。

答えて

1

本当の問題は、空のプロトコルを拡張していることです。

Heroにキャストすると、コンパイラはそれがPersonのサブクラスであることを認識し、拡張制約を満たします。

しかし、プロトコルPersonPresenter自体にキャストするとき、コンパイラは制約(Person)を満たすことができるかどうかを知りません。あなたは、プロトコルでの要件を宣言する場合

、それは動作します:

protocol PersonPresenter: class { 
    func displayName() 
} 
関連する問題