抽象型の種類
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/03/20 17:00 UTC 版)
抽象クラス(実装継承と型継承の混合) オブジェクト指向言語における抽象クラスとは、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での機能) トレイトが抽象型に当たるのかは諸説分かれる。トレイトは構造的型付け(英語版)に準拠しており、その本質は、クラスに機能注入するためのメソッドの集合体だからである。これをRubyはモジュールと呼び、Rakuはロールと呼んでいる。トレイトはSmalltalk処理系由来であり、Mix-inの作法もヒントになっていた。[要出典] 多重継承前提のトレイトは、主に関数型を取り入れたオブジェクト指向言語で様々に解釈されるようになり、その中にはインタフェースとの類似形もあったので、これが抽象型と見なされる一因になっている。[要出典] 型クラス(アドホック多相由来のジェネリック・サブタイピング) 元々の型クラスは純粋関数型言語で、関数のパラメータ型に制約(constraint)を付加して関数オーバーロードを可能にするための手段であり、そのオーバーロードをジェネリック化していた。制約の付加はアドホック多相と解釈された。その制約を、サブタイピングされるジェネリック抽象型にしてデータクラスやレコード型や構造体に継承できるようにしたものが、オブジェクト指向言語で言われる型クラスになっている。[要出典]
※この「抽象型の種類」の解説は、「抽象型」の解説の一部です。
「抽象型の種類」を含む「抽象型」の記事については、「抽象型」の概要を参照ください。
- 抽象型の種類のページへのリンク