LoginSignup
4
4

More than 5 years have passed since last update.

Protocolによるポリモーフィズム(多態性)

Last updated at Posted at 2018-02-04

概要

呼び出すメソッドは同じでも、オブジェクトの型によって振る舞いを変化させることをポリモーフィズム(多態性)と呼びます。本記事ではProtocolを使ったポリモーフィズムの実装例を紹介します。

背景

そもそも何故ポリモーフィズムを使う必要があるのでしょうか。ポリモーフィズムのメリットとして、「メソッドの呼び出し元でオブジェクトの具体的な型を知らなくても済む」という点が挙げられます。例えば、似たような性質を持つが厳密には異なる二つのクラス、クラスAとクラスBがあるとします。この二つのクラスは共に同名のメソッド(doSomethingとします)を持っていますが、その中の処理は異なるものとします。

もしdoSomethingの呼び出し元で、対象のオブジェクトがクラスAのインスタンスなのかクラスBのインスタンスなのか知らなければならないとしたら、その識別の処理を呼び出し元に書かなければなりません。また、同様の性質を持つクラスCやクラスDが将来作られた場合、やはり呼び出し元を修正してクラスCやクラスDを識別するコードを書く必要があります。

Protocolを使用して具体的な型を隠蔽することにより、呼び出し元のコードをそういった処理から解放することが可能になります。以下に具体例を示します。

Protocolの宣言と実装

まず、何らかの計算を行うcalculateメソッドを宣言したCaculatorProtocolがあるとします。

CalculatorProtocol
protocol CalculatorProtocol {
    // 何らかの計算を行うメソッド
    func calculate(num: Int) -> Int
}

次に、CalculatorProtocolを実装する二つのクラスを定義します。どちらもcalculateメソッドを実装していますが、一方は引数の2倍を返す処理、もう一方は引数の2乗を返す処理と、同名のメソッドで異なる処理を行っています。

DoubleCalculator
class DoubleCalculator: CalculatorProtocol {
    func calculate(num: Int) -> Int {
        // 引数の2倍を返す
        return num * 2
    }
}
SquareCalculator
class SquareCalculator: CalculatorProtocol {
    func calculate(num: Int) -> Int {
        // 引数の2乗を返す
        return num * num
    }
}

さらに、typeの値に応じてCalculatorProtocolオブジェクトを返すgetCalculatorメソッドを実装したCalculatorHandlerを用意します。

CalculatorHandler
class CalculatorHandler {
    func getCalculator(type: String) -> CalculatorProtocol? {
        if (type == "Double") {
            return DoubleCalculator()
        } else if (type == "Square") {
            return SquareCalculator()
        } else {
            return nil
        }
    }
}

使用例(呼び出し元)

最後に、これらを使用して実際にcalculateメソッドを呼んでみましょう。

calculateメソッドの呼び出し元
let type = "Square"
let num = 4

if let calculator: CalculatorProtocol = CalculatorHandler().getCalculator(type: type) {
    let result = calculator.calculate(num: num)
    print(String(result))
}

実行結果

16

呼び出し元では、calculatorオブジェクトがDoubleCalculatorのインスタンスなのか、SquareCalculatorのインスタンスなのかを判別していません。このようにしておけば、将来的にTripleCalculatorやCubeCalculatorといった新しいCalculatorProtocolの実装が現れても、呼び出し元を修正する必要がありません。このようにProtocolを活用することで抽象度を上げ、柔軟かつ保守性の高いコードを記述することが可能になります。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4