polymorphism
「polymorphism」の意味・「polymorphism」とは
「polymorphism」とは、英語で「多形性」という意味である。情報科学の分野では、同一のインターフェースで異なる動作をする機能のことを指す。また、生物学の分野では、同種の生物が異なる形質を示す現象を指す。例えば、情報科学の場合、同じ名前のメソッドでも引数の型や数によって異なる処理を行うことがある。生物学の場合、同じ種の蝶でも色や模様が異なることがある。「polymorphism」の発音・読み方
「polymorphism」の発音は、IPA表記では/pɒlɪ'mɔːfɪz(ə)m/である。IPAのカタカナ読みでは「ポリモーフィズム」となる。日本人が発音するカタカナ英語では「ポリモーフィズム」と読む。「polymorphism」の定義を英語で解説
Polymorphism is a term in English that refers to the ability of an object to take on many forms. In computer science, it refers to the ability of a variable, function, or object to take on multiple forms. In biology, it refers to the occurrence of different forms or types in the same population of a species.「polymorphism」の類語
「polymorphism」の類語としては、「multiformity」や「variability」がある。これらの単語も同様に、多様性や変異性を表す英語である。「polymorphism」に関連する用語・表現
「polymorphism」に関連する用語としては、「inheritance」(継承)や「encapsulation」(カプセル化)がある。これらはプログラミングにおけるオブジェクト指向の三大要素であり、「polymorphism」もその一つである。また、生物学の分野では、「genetic variation」(遺伝的変異)や「phenotypic variation」(表現型変異)が関連する。「polymorphism」の例文
以下に「polymorphism」を用いた例文を10個示す。 1. Polymorphism is one of the three main principles of object-oriented programming.(多形性はオブジェクト指向プログラミングの三大原則の一つである。) 2. The concept of polymorphism can be a bit difficult to understand for beginners.(多形性の概念は初心者にとって少し理解しにくいかもしれない。) 3. Polymorphism allows objects to be treated as instances of their superclass.(多形性により、オブジェクトはそのスーパークラスのインスタンスとして扱うことができる。) 4. In biology, polymorphism refers to the occurrence of different forms within the same population of a species.(生物学において、多形性は同一種の個体群内で異なる形態が存在する現象を指す。) 5. Genetic polymorphism is a common phenomenon in nature.(遺伝的多形性は自然界でよく見られる現象である。) 6. Polymorphism in programming can increase the flexibility and maintainability of the code.(プログラミングにおける多形性は、コードの柔軟性と保守性を高めることができる。) 7. The butterfly exhibits a striking example of polymorphism with its different color patterns.(その蝶は異なる色の模様で顕著な多形性を示している。) 8. Polymorphism is an important concept in both computer science and biology.(多形性は、コンピュータ科学と生物学の両方で重要な概念である。) 9. Understanding polymorphism can greatly improve your programming skills.(多形性を理解することは、プログラミングスキルを大いに向上させることができる。) 10. The study of polymorphism can provide insights into evolutionary processes.(多形性の研究は、進化過程についての洞察を提供することができる。)ポリモーフィズム
【英】polymorphism
ポリモーフィズムとは、「メッセージの送信側とメッセージの受信側が動的に決まる」というオブジェクト指向プログラミング言語が持つ性質のことである。
ポリモーフィズムは、オブジェクト指向設計の原則である「機能と実装の分離」を実現するために欠かせない機能で、オブジェクトを呼び出す側が意識しなくても実行時の条件に合った適切なメソッドが実行できる。ポリモーフィズムは、継承を利用しているため、オーバーライドと同様な機能に見えるが、ポリモーフィズムの場合は機能が置き換わるのではなく、同一名称メソッドであるが振る舞いは異なるメソッドとして働く。
なお、ポリモーフィズムの実現には、動的バインディングという機能がプログラミング言語に備わっている必要がある。SmalltalkやJavaなどは動的バインディングであるが、C++は静的バインディングである。そのため、C++では仮想関数を導入して実行時までバインディングを遅らせることでポリモーフィズムを実現している。
ポリモーフィズム
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/12/27 03:45 UTC 版)
型システム |
---|
主要カテゴリ |
静的型付け vs 動的型付け 強い vs 弱い 明示的 vs 型推論 名前的 vs 構造的 ダックタイピング |
マイナーカテゴリ |
部分型 再帰型 部分構造型 依存型 漸進的型付け フロータイピング 潜在的型付け |
型理論のコンセプト |
直積型 - 直和型 交差型 - 共用型 単一型 - 選択型 帰納型 - 精製型 トップ型 - ボトム型 函数型 - 商型 全称型 - 存在型 一意型 - 線形型 |
ポリモーフィズム(英: polymorphism)とは、それぞれ異なる型に一元アクセスできる共通接点の提供[1]、またはそれぞれ異なる型の多重定義を一括表現できる共通記号の提供[2]を目的にした、型理論またはプログラミング言語理論の概念および実装である。この用語は、有機組織および生物の種は様々な形態と段階を持つという生物学の概念からの借用語である[3]。多態性、多相性と邦訳されることが多い。
ポリモーフィズムは、通常以下の三種に分けられる。
- アドホック多相
- (ad hoc polymorphism)
- 恣意的な型の集合に一つの共通接点を提供する。関数オーバーロード、Mix-inのいち実装、型クラスなど。
- パラメトリック多相
- (parametric polymorphism)
- 詳細化されていない型要素を内包する抽象的な型に記号表現を提供する。ジェネリクスや関数型言語の型構築子など。
- サブタイピング
- (subtyping)
- サブタイプ多相(subtype polymorphism)やインクルージョン多相(inclusion polymorphism)とも。上位型をその下位型の数々で代替できるようにする[4]。オブジェクト指向の多態性はこれを指す。
この他に、ロー多相(row polymorphism)とポリタイピズム(polytypism)[注釈 1]も挙げられることがある。対義語はモノモーフィズム(Monomorphism)である。
歴史
ポリモーフィックな型システムの研究は1960年代から始められている。クリストファー・ストレイチーの1967年論文Fundamental Concepts in Programming Languagesで、アドホック多相とパラメトリック多相という概念が初めて提唱されている[6]。アドホック多相は「ALGOL68」で実践され、パラメトリック多相は「ML」の型システムで実践された。 1985年にピーター・ウェグナーとルカ・カーデリは「Simula67」の継承+動的ディスパッチを説明するためのインクルージョン多相という概念を提唱した[7]。これとストレイチー提唱の二つを合わせて三本柱にした概念が、ポリモーフィズムと呼ばれるようになっている。
1989年にオブジェクト指向の動的型付けを説明するためのロー多相という概念がミッチェル・ワンドの著作で提唱されているが、知名度は低い。同年にパラメトリック多相をモチーフにしたジェネリックプログラミングがアレクサンダー・ステパノフらの著作で提唱され、これはポリタイピズムとも呼ばれた[注釈 2]。
1980年代の「Ada」はジェネリクスに型制約と称する有界量化の概念を採用した。1990年代の「Haskell」はアドホック多相とジェネリクスを融合した型クラスを考案している。2003年の「Scala」はサブタイピング+ジェネリクスに共変性と反変性を導入した。
ポリモーフィズムの種類
アドホック多相
関数や演算子の多重定義のように、同じ名前で型の異なる引数に適用できて、その振る舞いは引数の型によって違うような関数の多相性のことを「アドホック多相」という。「ad hoc(その場しのぎの)」という用語は悪い意味で使われているのではなく、単にこの種の多相性が型システムの基本的な機能ではないという事実を指して使われている。次のC++での例では、Add
関数は呼び出し側からは様々な型に対して総称的に動作するかのように見えるが、コンパイラから見ればこれらは全く別個の2つの関数である。
#include <iostream>
#include <string>
int Add(int x, int y) {
return x + y;
}
std::string Add(const std::string& s1, const std::string& s2) {
return s1 + s2;
}
int main() {
std::cout << Add(1, 2) << std::endl; // "3" が出力される。
std::cout << Add("Hello, ", "World!") << std::endl; // "Hello, World!" が出力される。
}
動的型付け言語では、実行されるべき正しい関数が実行時まで決定できない可能性があるという点で、状況はより複雑になりうる。暗黙の型変換も型強制多相(coercion polymorphism)としてアドホック多相の一形態と定義される[7][8]。
パラメトリック多相
パラメトリック多相を使うと、値の型に関係なく「一様に」値を扱うことで、関数やデータ型を総称的に記述できるようになる[9]。パラメトリック多相は言語の静的な型安全性を保ちながら表現力を向上させる手法のひとつである。
パラメトリック多相の概念は関数とデータ型の両方に適用される。異なる型の値に対して評価、適用可能な関数のことを「多相な関数」という。総称化された型とみなすことができるデータ型(例えば任意の型の要素を持てるリスト)は「多相なデータ型」という。
パラメトリック多相性は関数型プログラミングの分野では至るところに現れるため、しばしば単に「多相性」と言われることがある。次のHaskellの例ではパラメータ化されたリストと2つのパラメトリック多相な関数を示す。
data List a = Nil | Cons a (List a)
length :: List a -> Integer
length Nil = 0
length (Cons x xs) = 1 + length xs
map :: (a -> b) -> List a -> List b
map f Nil = Nil
map f (Cons x xs) = Cons (f x) (map f xs)
パラメトリック多相は様々なオブジェクト指向言語でも利用できる。例えばC++やD言語のテンプレート、JavaやC#のジェネリクスなどである。
class List<T> {
class Node<T> {
T elem;
Node<T> next;
}
Node<T> head;
int GetLength() { ... }
}
List<B> Map(Func<A, B> f, List<A> xs) {
...
}
ジャン=イヴ・ジラールとJohn C. Reynoldsは、それぞれ独立に、パラメトリック多相の概念をラムダ計算の拡張(System Fや多相ラムダ計算と呼ばれる)として形式的に発展させた。
サブタイピング
いくつかのプログラミング言語では、特定の多相性の状況において使用できる型の範囲を制限するためにサブタイピングを採用している。サブタイピングを使用すると、ある型T
のオブジェクトを受け取る関数は、T
のサブタイプである型S
のオブジェクトを渡された場合でも正しく動作する(リスコフの置換原則)。この型の関係性はしばしばS <: T
と表記される。一般的にサブタイプ多相=インクルージョン多相は動的に解決される(後述)。
次のJavaの例ではAnimal
のサブタイプとしてCat
とDog
を用意する。メソッドletsHear()
はAnimal
型の引数を受け取るが、そのサブタイプの引数を渡しても問題なく動作する。
abstract class Animal {
abstract String talk();
}
class Cat extends Animal {
String talk() {
return "Meow!";
}
}
class Dog extends Animal {
String talk() {
return "Woof!";
}
}
class Test {
static void letsHear(final Animal a) {
System.out.println(a.talk());
}
public static void main(String[] args) {
letsHear(new Cat());
letsHear(new Dog());
}
}
オブジェクト指向言語は継承によってサブタイピングを提供する。典型的な実装では、各クラスはそれぞれ仮想関数テーブル(vtable)と呼ばれる関数のテーブルを持ち、各オブジェクトは自らのクラスのvtableへのポインタを持つ。多相なメソッドを呼び出すときには、このvtableを参照する。
多くのオブジェクト指向言語では、仮想関数の呼び出しに1番目の引数(this
オブジェクト)の vtable だけを参照する単一ディスパッチを採用している。つまりその他の引数の実行時の型は仮想関数の呼び出しに全く無関係である。一方でCommon Lispなどでは、メソッドの呼び出しが「全ての」引数に対して多相的となる多重ディスパッチを採用している。
ロー多相
この節は検証可能な参考文献や出典が全く示されていないか、不十分です。(2021年10月) |
ロー多相は、型理論におけるレコード型(record type)の直積的または総和的な可変長要素の構造分析から導き出された多態性であり、動的型付けおよび動的プログラミングを説明できる形式論理として紹介される。構造的型付け (structural typing) の多態性(多相性)はロー多相に分類されることがある[10]。構造的型付けに類似したダックタイピングの説明にも適している。
日本語では行多相[11]と訳されることもあれば、列多相[12]と訳されることもある。
ポリタイピズム
この節は検証可能な参考文献や出典が全く示されていないか、不十分です。(2021年10月) |
ポリタイピズムは、パラメトリック多相の亜流と言えるものである。パラメトリック多相での型が型変数を内包するという概念を、ポリタイピズムでは型が包装型を着脱するという概念に置き換えている。包装型=コンテナである。コンテナの着脱は圏論での関手に類似している。ポリタイピズムは、ジェネリックプログラミングを説明する多態性として扱われている。
ポリモーフィズムの実装的側面
静的な多態性と動的な多態性
ポリモーフィズムは実装がいつ選択されるかによって、静的(コンパイル時)か動的(実行時)かに区別できる。これはそれぞれ静的ディスパッチおよび動的ディスパッチとして知られ、さらにこれらに対応するポリモーフィズムはそれぞれ静的ポリモーフィズムおよび動的ポリモーフィズムと呼ばれる。後者は典型的には仮想関数などを通して実現される。
動的ディスパッチのオーバーヘッドが無いため、静的ポリモーフィズムはより高速に実行できるが、追加的なコンパイラの補助を必要とする。静的ポリモーフィズムではコンパイラやソースコード解析ツール、プログラマの目視による、より広範な静的解析(特に最適化)が可能となる。動的ポリモーフィズムはより柔軟だが速度はより遅くなる。例えば動的ディスパッチではダック・タイピングが可能で、動的にリンクされたライブラリはオブジェクトの型を知らなくても動作できるだろう。
典型的にはアドホック多相とパラメトリック多相は静的ポリモーフィズムとして動作し、サブタイプ多相は動的ポリモーフィズムとして動作する。しかし、奇妙に再帰したテンプレートパターンのような洗練されたテンプレートメタプログラミングを通して、サブタイプ多相で静的ポリモーフィズムを実現することも可能である。
単態性と多態性
ポリモーフィズムの対義語としてモノモーフィズム(monomorphism、単態性、単相性)という言葉が使われることがある。
モノモーフィックな型システムを持つプログラミング言語では、サブルーチン(言語によっては関数や手続きとも呼ばれる)はそれぞれ一意に識別される名前(識別子)と結びついており、従って異なる動作を実現するためには異なる名前を用いる必要があった。
例えば、何かの値を文字列形式に変換する最も単純な場合を考える。モノモーフィックな型システムを持つ言語では、次のように別々の関数になっていなければならない。
- 古典的な変換関数:
- 数値を文字列にする場合
string = StringFromNumber(number)
- 日付値を文字列にする場合
string = StringFromDate(date)
一方ポリモーフィックな型システムを持つ言語では、StringValue のような汎用の述語を定義し、型別にそれぞれ適切な変換方式を定義させることでオブジェクトの種別によらない抽象度の高い変換形式を実現できる。
- 多態的な変換方式:
- 見た目上、型によらない変換が可能
string = number.StringValue string = date.StringValue
関数オーバーロードをサポートする言語では、共通の名前を持ち、引数の型だけが異なる StringFrom のような関数を定義することもできる。
string = StringFrom(number) string = StringFrom(date)
無論、StringValueやStringFromの定義は型ごとに行なわなければならないので、総体として記述量が減少するとは限らない(継承やジェネリックプログラミングによるコードの再利用はありうる)。また、何をもって「正しい動作」とするのかはオブジェクトの設計に依存するため、多態を使いこなすにはシステム全体を見通す設計能力が要求される。
注釈
- ^ polytypismは他の分野で「多型性」と邦訳されることがある[5]。
- ^ ポリタイピックプログラミング(polytypic programming)はジェネリックプログラミングと同一視されることがある。Polytypic Programming in Haskell | SpringerLink
出典
- ^ Bjarne Stroustrup (2007年2月19日). “Bjarne Stroustrup's C++ Glossary”. 2017年3月8日閲覧。 “polymorphism – providing a single interface to entities of different types.”
- ^ Cardelli, Luca; Wegner, Peter (December 1985). “On understanding types, data abstraction, and polymorphism”. ACM Computing Surveys 17 (4): 471–523. doi:10.1145/6041.6042 .: "Polymorphic types are types whose operations are applicable to values of more than one type."
- ^ “Polymorphism”. The Java™ Tutorials: Learning the Java Language: Interfaces and Inheritance. Oracle. 2021年9月8日閲覧。
- ^ Conallen, J.; Engle, M.; Houston, K.; Maksimchuk, R.; Young, B.; Booch, G. (2007). Object-Oriented Analysis and Design with Applications (3rd ed.). Pearson Education. ISBN 9780132797443
- ^ 重和, 樋口「光の非視覚的作用と概日リズム : 生理的多型性へのアプローチ(生理人類学のキーワード"生理的多型性"の本質に迫る)」『日本生理人類学会誌』第18巻第1号、2013年、39–43頁、doi:10.20718/jjpa.18.1_39。
- ^ C. Strachey – Fundamental Concepts in Programming Languages http://www.itu.dk/courses/BPRD/E2009/fundamental-1967.pdf
- ^ a b Cardelli, Luca; Wegner, Peter (December 1985). “On understanding types, data abstraction, and polymorphism”. ACM Computing Surveys (New York, NY, USA: ACM) 17 (4): 471–523. doi:10.1145/6041.6042. ISSN 0360-0300 .
- ^ Allen B. Tucker (28 June 2004). Computer Science Handbook, Second Edition. Taylor & Francis. pp. 91–. ISBN 978-1-58488-360-9
- ^ Pierce, B. C. 2002 Types and Programming Languages. MIT Press.
- ^ Objects and Aspects: Row Polymorphism | Neel Krishnaswami, Department of Computer Science, Carnegie Mellon University
- ^ 実例によるPureScript
- ^ OCamlで構築するモダンWeb:型付きHTML5プログラミングの実際 | 有限会社ITプランニング | 今井 敬吾
関連項目
ポリモーフィズム (polymorphism)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/05/02 14:27 UTC 版)
「クラス (コンピュータ)」の記事における「ポリモーフィズム (polymorphism)」の解説
詳細は「ポリモーフィズム」を参照 クラスを継承する際に、スーパークラスの振る舞いをサブクラスの振る舞いで上書きする(置き換える)ことをオーバーライドという。あるサブクラスのインスタンスがオーバーライドされた振る舞いを持つ場合、インスタンスの具体的な内容(クラス)が分からなくても、インスタンスに対してその振る舞いを実行するよう指示すれば、見かけがスーパークラスと同じ(すなわちインターフェイスが同じ)でありながら、インスタンスの実際のクラスに応じて実行される振る舞い(処理内容)を変えることができる。このようにして、見かけが一緒なのに動作が変わることをポリモーフィズム(ポリモルフィズム)/多様性/多態性/多相性などという。
※この「ポリモーフィズム (polymorphism)」の解説は、「クラス (コンピュータ)」の解説の一部です。
「ポリモーフィズム (polymorphism)」を含む「クラス (コンピュータ)」の記事については、「クラス (コンピュータ)」の概要を参照ください。
- ポリモーフィズムのページへのリンク