Swift protocol extensionで共通処理を再利用する
生徒
「先生、Swiftのプロトコルにextensionを使うと便利って聞いたんですが、どういうことなんですか?」
先生
「それはとても大事なポイントです。プロトコルにextensionを使うと、共通の処理をまとめて書けて、いろいろな型で再利用できるようになります。」
生徒
「へえ!それってコードが短くなったり、わかりやすくなったりするんですか?」
先生
「その通りです。では実際にSwift protocol extensionを使った例を見てみましょう。」
1. protocol extensionとは?
Swiftのprotocol extensionとは、プロトコルに対してデフォルトの実装を提供する仕組みです。プロトコルは通常「こういう機能を持ってください」という契約だけを定義しますが、extensionを使うと「共通の処理」を直接追加できます。
例えるなら、学校のルールブック(プロトコル)に「朝の挨拶をしましょう」と書いてあるだけだと、人によってやり方がバラバラになります。そこでextensionで「挨拶は『おはようございます』と言う」と決めれば、みんなが共通の挨拶を使えるようになります。
2. 基本的な書き方
protocol extensionの基本的な書き方は次の通りです。
protocol プロトコル名 {
// 必要な機能を定義
}
extension プロトコル名 {
// 共通の処理を追加
}
こうすることで、プロトコルに準拠する型は自動的にその処理を利用できます。
3. 挨拶の共通処理を追加してみよう
次の例では、Greetableというプロトコルを作り、extensionで共通の挨拶処理を追加しています。
protocol Greetable {
func greet()
}
extension Greetable {
func greet() {
print("こんにちは!")
}
}
struct Student: Greetable {}
struct Teacher: Greetable {}
let s = Student()
let t = Teacher()
s.greet()
t.greet()
こんにちは!
こんにちは!
このように、StudentもTeacherも自分でgreet()を実装していないのに、extensionのおかげで共通の挨拶が使えるようになります。
4. デフォルト実装を上書きする
もし特定の型で独自の挨拶をしたい場合は、その型の中でメソッドを再定義すれば上書きできます。
struct FriendlyStudent: Greetable {
func greet() {
print("やあ!元気?")
}
}
let fs = FriendlyStudent()
fs.greet()
やあ!元気?
このように、共通処理をベースにしつつ、必要に応じてカスタマイズも可能です。
5. 計算プロパティを追加する
protocol extensionではメソッドだけでなく、計算プロパティも追加できます。例えば「名前を持つもの」に自己紹介を追加してみましょう。
protocol Named {
var name: String { get }
}
extension Named {
var description: String {
return "私は\(name)です。"
}
}
struct User: Named {
let name: String
}
let u = User(name: "太郎")
print(u.description)
私は太郎です。
このように、プロトコルに準拠するだけで自動的に便利なプロパティが利用できるようになります。
6. 共通処理を使うメリット
protocol extensionで共通処理を定義するメリットは大きく分けて3つあります。
- コードの重複を減らせる:同じ処理を毎回書かなくて済みます。
- 保守性が高まる:修正が必要なときに一か所直すだけで済みます。
- 柔軟にカスタマイズできる:デフォルトを使いつつ、必要なら独自実装で上書き可能です。
これにより、アプリ開発の効率が上がり、エラーも減らせます。
7. 注意点
便利なprotocol extensionですが、注意点もあります。
- extensionで定義したメソッドは「動的な多態性(オーバーライドの仕組み)」が効かない場合があります。
- 使いすぎると「どこで実装されているのか」がわかりにくくなることがあります。
- プロトコルの役割を明確にして、必要な共通処理だけをextensionに書くようにしましょう。