Rubyで理解するポリモーフィズムから、Goのインターフェースへ①

#何を書くか
私は現在、Go言語の学習に取り組んでいます。
そこで、**「インターフェース」**という概念を学びました。

##何やこれ
正直、教本を読んでも全然なんのこっちゃと言った感じだったので、[こちら](https://qiita.com/k-penguin-sato/items/885a61d819cc431304f5)の記事を覗いてみました。

すると

>interface(インターフェース) を利用することで、オブジェクト指向言語でいうところのポリモーフィズムと同様の機能を実現できます。

との説明がありました。ふむふむ。ポリモーフィズムね。

何だそりゃ。

##ということで
Rubyの学習も兼ねて、まずはオブジェクト指向のポリモーフィズムを理解し、それからインターフェースを学習していこうと思います。

一応二部作の予定で書いていきます。
1部目の今回は、**ポリモーフィズム**について、自分が調べただけつらつらとお話ししていこうと思います。

#ポリモーフィズムとは
**オブジェクト指向言語(Rubyが持つプログラミング言語が持つ概念的な捉え方)**には、守べき設計方針と呼べるような三大要素が存在します。

>「カプセル化、継承、ポリモーフィズム」

の3つです。

まず、ポリモーフィズムは、オブジェクト指向言語を利用する際に、押さえておかないといけない考えであることがわかります。

それでは、なぜポリモーフィズムを守らないといけないのでしょうか。

その前に、まずは、直訳から見ていきましょう。

##ポリモーフィズム(Polymorphism)の直訳
この単語は、二つにわけて考えます。
poly = 「多様な、多くの」
morphism = 「変化」

まとめると、多くの変化、多様な変化と言ったところでしょうか。
より端的な言葉でまとめるために、この記事では**「多様性」**で統一しようと思います。

余談ですが、メタモルフォーゼというものがありましたね。
あれも、変身する時に用いられる宣言だったように、"morphos"には変化みたいな意味があることは間違いなさそうです。

>メタモルフォーゼ（ドイツ語: Metamorphose）は変化、変身の意。

##ポリモーフィズムが守られるわけ
さて、ポリモーフィズムは、多様性である。ということが理解できました。
しかし、もちろんこれだけでは、意味がわかりませんので、具体的な例も交えながらポリモーフィズムを理解していきましょう。

例えば、動物を例にとってみましょう。

犬は、「ワン！」と鳴きます。
このことをプログラム化してみましょう。

```dog.rb
class dog
  def cry 
    puts "ワン！"
  end
end
```
こんな感じになるでしょう。

猫はどうでしょう。
同じ「鳴く」という動作は持っていますが、「ニャン」と鳴きます。

このことをプログラム化してみましょう。

```cat.rb
class cat
  def cry 
    puts "ニャン"
  end
end
```
こんな感じになるでしょう。

##共通しているものはまとめようよう、の前に
以上の二つの例を見てもらうと、`cry`というメソッドが共通していることがわかると思います。
なんとなく、**一つにまとめられそうだな、とも考えた方もいるかもしれません**が、ここからが**ポリモーフィズムの考え方の真骨頂**なので落ち着いて考えてください。

先ほど、ポリモーフィズムは多様性であると述べました。
今回も、「鳴く」という行為に、「ワン！」とか「ニャン」とかいう、多様性を見て取ることができました。

このように、**「一つにまとめても、その後の展開によって多様性が担保されそうな状況で、コードをすっきりさせようぜ！という目的で考えるべきなのが、ポリモーフィズム」**です。

まだ、だいぶわかりにくいかもしれないので、実際のコードを元に考えていきましょう。

##プログラミングの特性を利用する

先ほどオブジェクト指向言語の守るべき３ヶ条をあげました。

>「カプセル化、継承、ポリモーフィズム」

でしたね。そこで、継承を利用して、先ほどの`cry`メソッドを継承させる形で記述してみましょう。

```animal.rb
class Animal

  attr_accessor :name

  def cry(say="")
    "#{self.name}: #{say}"
  end

end

class Dog < Animal
  def cry(voice='ワン！')
    super #(voice="ワン！")を引数にして、メソッドを呼び出す。
  end
end

class Cat < Animal 
  def cry (voice='ニャン')
    super　#(voice="ニャン")を引数にして、メソッドを呼び出す。
  end
end
  


my_dog = Dog.new
my_dog.name = 'ジョン'

your_cat = Cat.new
your_cat.name = 'パトリシア'

my_dog.cry     #=>ジョン: ワン！
your_cat.cry     #→パトリシア: ニャン
```

という風に、共通していた`cry`メソッドを、上位のAnimalクラスで宣言しました。このクラスを、`Dog`, `Cat`それぞれのクラスが継承し、それぞれ中身を作ってインスタンスを形成できるようにしました。

**呼び出されたクラス(Animal)は、呼び出し元（Dog, Cat）で、それぞれに適した振る舞いを行う。**
このように

>「中に入るものによって同じ関数でも違う処理を行える」というプログラミング言語自体の特徴

そのものを、ポリモーフィズムと呼ぶのです。

##まとめ
####- ポリモーフィズムは、オブジェクト指向の「全てをモノとして捉える」という考え方に必須のものである。
現実のものには、共通する部分が何かしらある。それを多様なものによって用いられるような形でまとめておこう。

####- Rubyでは特に、上位クラスへのメソッド共通化でその特徴が現れる。
共通するところはまとめて、それぞれのオブジェクトに対応できるような（＝多様な利用に備えられるような）形でプログラムを生成していこう。

↓

- コードがきれいにまとまる
- プログラムの変更に強くなる柔軟性

というメリットにつながる。

以上の事実が、ポリモーフィズムをオブジェクト指向が３ヶ条に据えるわけなんだと思います。

##最後に
最後まで読んでいただき、ありがとうございます。
ソースコード、記事の書き方について「もっとこうしたほうがいいよ！」というご意見、「そこどうなっているの？」というご質問など、お待ちしております。

##参考文献
- [ポリモーフィズムとはなにか？超わかりやすく解説します！](https://jpazamu.com/polymorphism/)
- [「ポリモーフィズムって何？」をRubyを使って説明してみた](https://qiita.com/katsutakashima/items/81dc762a06bbea02cc97)
- [オブジェクト指向の3大要素 まとめ](https://qiita.com/yuto-ktok/items/2c8172397ba9dc76fe7a)
- [Rubyのポリモーフィズムとは【初心者向け】](https://techacademy.jp/magazine/19473)