ダック・タイピング
ダック・タイピング(duck typing)とは、Smalltalk、Python、Rubyなどのいくつかの動的型付けオブジェクト指向プログラミング言語に特徴的な型付けの作法のことである。それらの言語ではオブジェクト(変数の値)に何ができるかはオブジェクトそのものが決定する。つまり、オブジェクトがあるインタフェースのすべてのメソッドを持っているならば、たとえそのクラスがそのインタフェースを宣言的に実装していなくとも、オブジェクトはそのインタフェースを実行時に実装しているとみなせる、ということである。それはまた、同じインタフェースを実装するオブジェクト同士が、それぞれがどのような継承階層を持っているのかということと無関係に、相互に交換可能であるという意味でもある。
この用語の名前は「ダック・テスト」に由来する。
"If it walks like a duck and quacks like a duck, it must be a duck"
(もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである)
デーブ・トーマスはRubyコミュニティで初めてこの言葉を使ったと考えられている。
C++のtemplateはダック・タイピングの静的版である。例えば、各種のiteratorはIterator基底クラスのようなものからメソッドを継承しているわけではないが、同じ構文でコンパイルが通るならば、それはiteratorの一種として扱える。C++で言う「同じインターフェースを持つ」とは、コンパイラにとってインターフェースが同じだということである。したがって、iteratorの実装はオブジェクトである必要すらない。
もう1つ、ダック・タイピングに似たアプローチにOCamlのstructural subtypingがある。メソッドのシグネチャが互換ならば、宣言上の継承関係は関係なくとも、オブジェクトの型は互換であるというものである。これはOCamlの型推論システムによってコンパイル時にすべて決定される。
目次 |
Rubyでの例 [編集]
Rubyでの単純な例を示す。
def test(foo) puts foo.sound end class Duck def sound 'quack' end end class Cat def sound 'myaa' end end test(Duck.new) test(Cat.new)
出力は以下である。
quack myaa
2つのクラスに継承の関係が無いことに注目して欲しい。
C++での例 [編集]
上記Rubyの例をC++で記述すると、以下のようになる。
#include <iostream> template <class T> void test(const T& t) { std::cout << t.sound() << std::endl; } struct Duck { const char* sound() const { return "quack"; } }; struct Cat { const char* sound() const { return "myaa"; } }; int main() { test(Duck()); test(Cat()); }
実行結果はRubyの例と同じである。