Swiftのdefault implementationを徹底解説!ExtensionとProtocolで実装重複を解消する方法
生徒
「先生、Swiftのプログラムを書いていると、同じようなメソッドを何度も書くことになってしまうんですが、もっと簡単にする方法はありますか?」
先生
「とてもいいポイントに気づいたね。Swiftにはprotocolとextensionを使って、同じ処理を一度だけ書いて使い回す仕組みがあるんだ。その仕組みをdefault implementationと呼ぶよ。」
生徒
「default implementationってなんですか?」
先生
「直訳すると『標準の実装』という意味だね。protocolに対してextensionを使って共通処理を実装しておくと、それを自動的に使えるようになるんだよ。」
1. ProtocolとExtensionの基本
まずは基礎をおさらいしましょう。protocol(プロトコル)は「設計図」や「ルールブック」のようなものです。例えば、「走ることができる」というルールを定義するならprotocol Runnableを作れます。そして、クラスや構造体がそのルールに従うと宣言すると、その機能を実装する必要があります。
しかし、毎回同じような実装を繰り返すのは非効率です。そこで役立つのがextension(拡張機能)です。extensionを使えば、protocolに対してあらかじめ「共通の実装」を追加することができ、それがdefault implementationになります。
2. default implementationの仕組み
default implementationとは、protocolの機能を拡張して「デフォルトの動作」を提供する仕組みです。これにより、同じ処理を何度も書く必要がなくなり、コードがすっきりします。
protocol Runnable {
func run()
}
extension Runnable {
func run() {
print("とりあえず走ります!")
}
}
この例では、Runnableというprotocolに対して「走る」という動作をデフォルトで定義しました。これにより、実装側はrun()を省略できます。
3. 実際に使ってみよう
それでは、クラスで実際にdefault implementationを利用してみましょう。
struct Dog: Runnable { }
struct Cat: Runnable {
func run() {
print("猫は静かに走ります")
}
}
let dog = Dog()
dog.run() // デフォルトの「とりあえず走ります!」
let cat = Cat()
cat.run() // 「猫は静かに走ります」
とりあえず走ります!
猫は静かに走ります
Dogは自分でrun()を定義していないので、デフォルトの実装が使われます。一方Catは独自の実装を持っているので、そのコードが優先されます。
4. default implementationのメリット
default implementationを使うと以下のようなメリットがあります。
- コードの重複を減らせる
- 共通処理を一か所にまとめられる
- 必要に応じて独自の実装に上書きできる
特に、大規模なアプリや複数の構造体・クラスで同じ処理を使いたい場合に効果を発揮します。初心者の方にとっても、シンプルなコードで全体像を理解しやすくなるという利点があります。
5. 現実世界の例えで理解する
学校のクラブ活動を例に考えてみましょう。すべての部活は「活動をする」というルールがあります。もし一つひとつの部活が「活動の挨拶」を毎回違う先生に書いてもらっていたら大変ですよね。そこで、「全員で最初に『よろしくお願いします!』と言う」という共通ルールを決めておけば、各クラブはそのまま使えます。でも、ダンス部だけは特別な挨拶をしたいと思ったら、自分たちで別の挨拶を作っても構いません。
この仕組みがSwiftのdefault implementationと同じです。基本は共通ルールに従いつつ、必要に応じて独自のやり方も認められるのです。
6. 補足として
Swiftでのprotocolとextensionの組み合わせは、現場でもよく使われるテクニックです。特にdefault implementationを知っていると、同じ処理を繰り返し書かずに済むため、開発が効率的になります。また、初心者がプロの書いたコードを読んだときにも「なぜ同じ処理が省略されているのか」を理解できるようになります。