既存の型のソースコードにアクセスできない場合であっても、新しいプロトコルを採用し準拠するよう既存の型を拡張することができます。エクステンションで、既存の型に新しいプロパティやメソッド、サブスクリプトを追加することができ、プロトコルが要求するあらゆる要件を追加することができます。エクステンションについての詳細は、Extensions を確認してください。
例えば、このプロトコル TextRepresentable
は、テキストで表現するための手段として、あらゆる型に実装することができます。それ自体の説明であり、現在の状態をテキストで表現します。
protocol TextRepresentable {
var textualDescription: String { get }
}
前に見た Dice
クラスが、TextRepresentable
を採用し準拠するよう拡張することができます。
extension Dice: TextRepresentable {
var textualDescription: String {
return "A \(sides)-sided dice"
}
}
このエクステンションは、Dice
がオリジナルの実装としてプロトコルを持っているかのように、新しいプロトコルを採用します。 プロトコル名は型名の後にコロンで区切って記述し、エクステンションの波括弧内にすべてのプロトコル要件を実装します。
この時点で、すべての Dice
インスタンスを TextRepresentable
として扱うことができます。
let d12 = Dice(sides: 12, generator: LinearCongruentialGenerator())
print(d12.textualDescription)
// "A 12-sided dice" と出力
同様に、SnakesAndLadders
ゲームクラスを TextRepresentable
プロトコルを採用し準拠するよう拡張することができます。
extension SnakesAndLadders: TextRepresentable {
var textualDescription: String {
return "A game of Snakes and Ladders with \(finalSquare) squares"
}
}
print(game.textualDescription)
// "A game of Snakes and Ladders with 25 squares" と出力
エクステンションでプロトコル採用を宣言
型があるプロトコルのすべての要件に準拠しているが、そのプロトコルを採用すると示していない場合、空のエクステンションでそのプロトコルを採用させることができます。
struct Hamster {
var name: String
var textualDescription: String {
return "A hamster named \(name)"
}
}
extension Hamster: TextRepresentable {}
この時点で、TextRepresentable
型が求められるところに Hamster
のインスタンスを使用することができます。
let simonTheHamster = Hamster(name: "Simon")
let somethingTextRepresentable: TextRepresentable = simonTheHamster
print(somethingTextRepresentable.textualDescription)
// "A hamster named Simon" と出力
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.