抽象型

抽象型(ちゅうしょうがた、: abstract type)とは、コンピュータプログラミング型システムのうち、名前的型システム (nominal / nominative type system) [注釈 1][1]における型の一種であり、直接インスタンス化することができないという特徴を持つ。対義語は具象型: concrete type)であり、具象型はインスタンス化することができる。抽象型の変数に格納された実際の値は、何らかの存在型英語版 (existential type) を持つ[2]

抽象型は実装を提供しないか、あるいは不完全な実装を提供する。具体的な形態や仕様はプログラミング言語ごとに異なるが、いくつかの言語において、実装を持たない抽象型はインタフェース (interface) やプロトコル英語版 (protocol) などと呼ばれている。クラスベースのオブジェクト指向プログラミング言語では、抽象型は抽象クラス (abstract class) [注釈 2]として実装され、具象型は具象クラス (concrete class) として実装される。

例えばJavaでの抽象型は、抽象クラスインタフェースである。ただし抽象クラスはabstractという宣言が付与されたクラスのことであり、抽象メソッドを含むこともあれば、含まないこともある[3]。また、メソッドのシグネチャを一切含まない空のインタフェースを定義することもできる。

抽象型の表記方法

[編集]

抽象クラスは、以下のようないくつかの方法で生成され、示され、シミュレートされる。

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

抽象型の性質

[編集]

抽象型は、静的型付けのオブジェクト指向言語において重要な機能である。動的型付け言語の場合は、ダック・タイピングがあるので抽象型は不要であり、等価な機能は存在しないものが多かったが、名前的型付け (nominal typing) の安全性や利便性を享受する観点から抽象型を導入した事例もある[4]

派生型のないクラスを「リーフクラス」とし、それ以外を抽象クラスに分類している書籍もある[5]

抽象型は、派生型が実装すべきメソッド群をプロトコルとして規定することができる。抽象型のインスタンスは直接生成できず、派生型は全ての必要な機能を実装しなければならない。このことはプログラムの正当性を保証する役割を担っている。

抽象型の種類

[編集]

抽象クラス(実装継承と型継承の混合)

オブジェクト指向言語における抽象クラスとは、abstractを明示的に宣言されたクラスか、抽象メソッド(メソッドシグネチャの宣言のみで、実際のコードが実装されていないメソッド)を含むクラスである。通常のクラスと異なり、インスタンス化はできない。
実装の多重継承には技術的問題があるため、多くのオブジェクト指向言語では、直接には単一の基底クラスしか継承できない。複数の基底型から成る派生型の定義 (subtyping) をサポートするため、多重継承を「実装継承」ではなく「型継承」に限定する目的で、抽象クラスとは別の純粋な抽象型(インタフェース)を定義する機構を備えた言語もある[6]

インタフェース(純粋な型継承)

Javaなどにはインタフェースがある。Javaのインタフェースはメソッドのシグネチャや定数を持つことができるが、メソッドの実装や変数(フィールド)を持つことはできない。Javaのクラスは複数のインタフェースを実装 (implement) できる。インタフェースは抽象メンバーのみを含む抽象クラスに似ているが、多重継承できる点が異なる。
Java 8やC# 8のように、言語仕様の改訂によりインタフェースに静的メソッドを定義したり、デフォルト実装を提供したりすることもできるようになったケースもある[7][8]
Javaにおける抽象クラスは、インタフェースを実装し、いくつかのメソッドのシグネチャを定義していることもあるが、一方でキーワード abstract により抽象化されたままのメソッドを持っている。クラスが実装すると宣言したインタフェースのすべてのメソッドの実装を提供していない場合、そのクラスはabstractとして宣言されなければならない。
C#では、クラスが実装すると宣言したインタフェースのすべてのメソッドの実装を提供する必要がある。

プロトコル(純粋な型継承)

Objective-CSwiftにはプロトコルがある[9][10]。プロトコルはメソッドやプロパティの宣言を持つことができるが、それらの実装や変数(状態)を持つことはできない。Objective-Cのクラスや、Swiftのクラス・構造体・列挙型は複数のプロトコルを採用 (adopt) できる。
Objective-CとSwiftのプロトコルでは、インスタンスメンバーだけでなく、クラスメンバー(静的メンバー)の宣言を持つこともできる。プロトコルを採用する型は、それらの実装を提供しなければならない。プロトコルのメンバーにはrequiredとoptionalの種別があり、requiredの実装は必須だが、optionalの実装は任意である。
Swift 2.0では、プロトコル拡張 (protocol extension) により、既存のプロトコルにメソッドの実装やcomputedプロパティの実装を追加することができるようになった[11][12]。プロトコル拡張により、メソッドやプロパティのデフォルト実装を提供することもできる。Swiftの「拡張」はObjective-Cの「カテゴリ」に似た言語機能であり、既存の型に対して変更を加えることなく機能を追加することができる[13]。ただし、プロトコル自身は依然として実装や状態を持つことはできない。

トレイトMix-inでの機能)

トレイトが抽象型に当たるのかは諸説分かれる。トレイトは構造的型付け英語版に準拠しており、その本質は、クラスに機能注入するためのメソッドの集合体だからである。これをRubyはモジュールと呼び、Rakuはロールと呼んでいる。トレイトはSmalltalk処理系由来であり、Mix-inの作法もヒントになっていた。[要出典]
多重継承前提のトレイトは、主に関数型を取り入れたオブジェクト指向言語で様々に解釈されるようになり、その中にはインタフェースとの類似形もあったので、これが抽象型と見なされる一因になっている。[要出典]

型クラス(アドホック多相由来のジェネリックサブタイピング

元々の型クラスは純粋関数型言語で、関数のパラメータ型に制約(constraint)を付加して関数オーバーロードを可能にするための手段であり、そのオーバーロードをジェネリック化していた。制約の付加はアドホック多相と解釈された。その制約を、サブタイピングされるジェネリック抽象型にしてデータクラスやレコード型構造体に継承できるようにしたものが、オブジェクト指向言語で言われる型クラスになっている。[要出典]

脚注

[編集]

注釈

[編集]
  1. ^ : nominalは公称的、名目的または記名的とも訳される。
  2. ^ 抽象基底クラス (abstract base class) とも。

出典

[編集]
  1. ^ Benjamin C. Pierce「19.3 名前的型システムと構造的型システム」『型システム入門 −プログラミング言語と型の理論−』オーム社、2013年3月26日。ISBN 978-4274069116 
  2. ^ Mitchell, John C.; Plotkin, Gordon D.; Abstract Types Have Existential Type, ACM Transactions on Programming Languages and Systems, Vol. 10, No. 3, July 1988, pp. 470–502
  3. ^ Abstract Methods and Classes (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)
  4. ^ 29.7. abc --- 抽象基底クラス — Python 3.6.13 ドキュメント
  5. ^ Riel, Arthur (1996). Object-Oriented Design Heuristics. Addison-Wesley Professional. p. 89. ISBN 020163385X 
  6. ^ Michael Kölling. “進化するJavaインタフェース - Javaの多重継承を理解する -”. 2021年11月29日閲覧。
  7. ^ Default Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)
  8. ^ インターフェイス - C# リファレンス | Microsoft Docs
  9. ^ コードをもっとオブジェクティブに:Cocoaの素、Objective-Cを知ろう(6)(2/4 ページ) - @IT
  10. ^ Protocols — The Swift Programming Language (Swift 5.5)
  11. ^ Swiftにおけるプロトコル指向プログラミング | InfoQ
  12. ^ Protocols — The Swift Programming Language (Swift 5.5), §Protocol Extensions
  13. ^ Extensions — The Swift Programming Language (Swift 5.5)

参考文献

[編集]
  • Types and Programming Languages by Benjamin Pierce (MIT Press 2002) [1]
  • More Effective C++: 35 New Ways to Improve Your Programs and Designs by Scott Meyers (1995) ISBN 0-201-63371-X

外部リンク

[編集]

関連項目

[編集]