第127回 Ruby vs Java ダックタイピングとインタフェースで見る多態性
前回は、Perlで書いたのだけど、
Rubyでも書いてみたので載せます。
動的型付け言語と静的型付け言語における多態性
オブジェクト指向では、多態性(ポリモーフィズム)という発想がでてくる。
この多態性を実現する方法を今回は2つ紹介する。
Rubyは動的型付け言語であり、ダックタイピングという手法で、多態性を実現できる。
対して、静的型付け言語であるJavaでは上位の型を作ることで多態性を実現できる(今回はインタフェースを用いてみた)。
ダックタイピング
Rubyでのタックタイピングを見てみよう。
human = Human.new dog = Dog.new duck = Duck.new human.touch(dog) human.touch(duck)
いま、このようにhumanがtouchすると、おのおのの動物が鳴くソースを書いてみる。
duck(アヒル)はhuman(人間)に触られると「ガーガー」と鳴き、
dog (犬)はhuman(人間)に触れると「ワンワン」と鳴くとする。
全体のソース:
class Dog def say puts 'ワンワン' end end class Duck def say puts 'ガーガー' end end class Human def touch(o) o.say end end human = Human.new dog = Dog.new duck = Duck.new human.touch(dog) human.touch(duck)
結果:
ガーガー ワンワン
これは何がすごいかというと、
class Human def touch(o) o.say end end
の o.sayのoがduckならDuckのsayが呼ばれ、 oがdogならばDogのsayが呼ばれているところである。
Javaは型を書かないといけない
Javaでは引数に受け取る型を書かないといけないので、DuckとDogを受け取ることができない。
Humanクラスのtouchメソッドに注目してほしい。
public class Human { public Human() { // ただのコンストラクタ } public void touch(Dog dog){ //型を決めないといけない dog.say(); } }
public class Duck { public Duck() { // ただのコンストラクタ } public void say() { System.out.println("ガーガー"); } }
public class Dog { public Dog() { // ただのコンストラクタ } public void say() { System.out.println("ワンワン"); } }
public class Main { /** * @param args */ public static void main(String[] args) { Human human = new Human(); Duck duck = new Duck(); Dog dog = new Dog(); human.touch(duck); human.touch(dog); } }
結果:
コンパイルエラー
インタフェース
そこで、JavaではDuckとDog以外にさらに上位の概念であるAnimalという型を作ってやる。今回はこれをインタフェースで実現する。
public interface Animal { public void say(); }
DuckとDogはこのAnimalを実装し、
Humanのtouchメソッドは、Animal型を受け取るように書き換える。
public class Human { public Human() { // ただのコンストラクタ } public void touch(Animal o){ //型を決めないといけない o.say(); } }
public class Duck implements Animal{ public Duck() { // ただのコンストラクタ } public void say() { System.out.println("ガーガー"); } }
public class Dog implements Animal{ public Dog() { // ただのコンストラクタ } public void say() { System.out.println("ワンワン"); } }
public class Main { /** * @param args */ public static void main(String[] args) { Human human = new Human(); Duck duck = new Duck(); Dog dog = new Dog(); human.touch(duck); human.touch(dog); } }
結果:
ガーガー ワンワン
このように、明示的に型を書かないといけない言語では、
さらに上位の型を作らなければ、柔軟なことをしにくい。