抽象型

抽象型（ちゅうしょうがた、abstract type）とは、コンピュータプログラミングの型システムのうち、名前的型システム (lang|en|nominal / nominative type system) における型の一種であり、直接インスタンス化することができないという特徴を持つ。対義語は具象型（concrete type）であり、具象型はインスタンス化することができる。抽象型の変数に格納された実際の値は、何らかのType system#Existential types (existential type) を持つ。
抽象型は実装を提供しないか、あるいは不完全な実装を提供する。具体的な形態や仕様はプログラミング言語ごとに異なるが、いくつかの言語において、実装を持たない抽象型はインタフェース (interface) やlabel=プロトコル (protocol) などと呼ばれている。クラスベースのオブジェクト指向プログラミング言語では、抽象型は抽象クラス (abstract class) 抽象基底クラス (abstract base class) とも。として実装され、具象型は具象クラス (concrete class) として実装される。
例えばJavaでの抽象型は、抽象クラスとインタフェースである。ただし抽象クラスはabstractという宣言が付与されたクラスのことであり、抽象メソッドを含むこともあれば、含まないこともある。また、メソッドのシグネチャを一切含まない空のインタフェースを定義することもできる。

**抽象型の表記方法**
抽象クラスは、以下のようないくつかの方法で生成され、示され、シミュレートされる。- JavaやC#では、クラス定義の際に明示的にキーワード abstract を付与することで抽象クラスであることを示す。- クラス定義の中で、クラスがそのプロトコルの一部として受容することを宣言されているが、実装は提供されないメソッド（抽象メソッド、C++では純粋仮想関数と呼ぶ）を含む場合、そのクラスは抽象クラスである。- 抽象型を継承するが、実装が必要な機能（抽象メソッド）をすべてオーバーライドしないクラスもまた抽象クラスである。- Smalltalkなどの動的型付き言語では、自分自身 (this) へ送信するメソッドが実装されていない場合、そのクラスは抽象クラスと見なせる。（ただし、このような実装は単なるバグの可能性もあり、実行してみるまでエラーであることが検出できない。）

**抽象型の性質**
抽象型は、静的型付けのオブジェクト指向言語において重要な機能である。動的型付け言語の場合は、ダック・タイピングがあるので抽象型は不要であり、等価な機能は存在しないものが多かったが、名前的型付け (nominal typing) の安全性や利便性を享受する観点から抽象型を導入した事例もある。
派生型のないクラスを「リーフクラス」とし、それ以外を抽象クラスに分類している書籍もある。
抽象型は、派生型が実装すべきメソッド群をプロトコルとして規定することができる。抽象型のインスタンスは直接生成できず、派生型は全ての必要な機能を実装しなければならない。このことはプログラムの正当性を保証する役割を担っている。

**抽象型の種類**
抽象クラス（実装継承と型継承の混合）
 オブジェクト指向言語における抽象クラスとは、abstractを明示的に宣言されたクラスか、抽象メソッド（メソッドシグネチャの宣言のみで、実際のコードが実装されていないメソッド）を含むクラスである。通常のクラスと異なり、インスタンス化はできない。
 実装の多重継承には技術的問題があるため、多くのオブジェクト指向言語では、直接には単一の基底クラスしか継承できない。複数の基底型から成る派生型の定義 (subtyping) をサポートするため、多重継承を「実装継承」ではなく「型継承」に限定する目的で、抽象クラスとは別の純粋な抽象型（インタフェース）を定義する機構を備えた言語もある。
インタフェース（純粋な型継承）
 Javaなどにはインタフェースがある。Javaのインタフェースはメソッドのシグネチャや定数を持つことができるが、メソッドの実装や変数（フィールド）を持つことはできない。Javaのクラスは複数のインタフェースを実装 (implement) できる。インタフェースは抽象メンバーのみを含む抽象クラスに似ているが、多重継承できる点が異なる。
 Java 8やC# 8のように、言語仕様の改訂によりインタフェースに静的メソッドを定義したり、デフォルト実装を提供したりすることもできるようになったケースもある。
 Javaにおける抽象クラスは、インタフェースを実装し、いくつかのメソッドのシグネチャを定義していることもあるが、一方でキーワード abstract により抽象化されたままのメソッドを持っている。クラスが実装すると宣言したインタフェースのすべてのメソッドの実装を提供していない場合、そのクラスはabstractとして宣言されなければならない。
 C#では、クラスが実装すると宣言したインタフェースのすべてのメソッドの実装を提供する必要がある。
プロトコル（純粋な型継承）
 Objective-CとSwiftにはプロトコルがある。プロトコルはメソッドやプロパティの宣言を持つことができるが、それらの実装や変数（状態）を持つことはできない。Objective-Cのクラスや、Swiftのクラス・構造体・列挙型は複数のプロトコルを採用 (adopt) できる。
 Objective-CとSwiftのプロトコルでは、インスタンスメンバーだけでなく、クラスメンバー（静的メンバー）の宣言を持つこともできる。プロトコルを採用する型は、それらの実装を提供しなければならない。プロトコルのメンバーにはrequiredとoptionalの種別があり、requiredの実装は必須だが、optionalの実装は任意である。
 Swift 2.0では、プロトコル拡張 (protocol extension) により、既存のプロトコルにメソッドの実装やcomputedプロパティの実装を追加することができるようになった。プロトコル拡張により、メソッドやプロパティのデフォルト実装を提供することもできる。Swiftの「拡張」はObjective-Cの「カテゴリ」に似た言語機能であり、既存の型に対して変更を加えることなく機能を追加することができる。ただし、プロトコル自身は依然として実装や状態を持つことはできない。
トレイト（Mix-inでの機能）
 
 要出典範囲|date=2021-11|多重継承前提のトレイトは、主に関数型を取り入れたオブジェクト指向言語で様々に解釈されるようになり、その中にはインタフェースとの類似形もあったので、これが抽象型と見なされる一因になっている。
型クラス（アドホック多相由来のジェネリック・サブタイピング）
 要出典範囲|date=2021-11|元々の型クラスは純粋関数型言語で、関数のパラメータ型に制約（constraint）を付加して関数オーバーロードを可能にするための手段であり、そのオーバーロードをジェネリック化していた。制約の付加はアドホック多相と解釈された。その制約を、サブタイピングされるジェネリック抽象型にしてデータクラスやレコード型や構造体に継承できるようにしたものが、オブジェクト指向言語で言われる型クラスになっている。

**脚注**

**注釈**

**出典**

**参考文献**
 Types and Programming Languages by Benjamin Pierce (MIT Press 2002) - More Effective C++: 35 New Ways to Improve Your Programs and Designs by Scott Meyers (1995) ISBN 0-201-63371-X

**外部リンク**
  Traits: Composable Units of Behavior by Nathanael Schärli, Stéphane Ducasse, Oscar Nierstrasz and Andrew Black

**関連項目**
 インタフェース (抽象型)- 型システム- 型理論