「インタフェース (抽象型)」の版間の差分

削除された内容 追加された内容
m編集の要約なし
タグ: モバイル編集 モバイルウェブ編集 改良版モバイル編集
Sycgln (会話 | 投稿記録)
(同じ利用者による、間の2版が非表示)
1行目:
'''インタフェース''' ({{lang-en-short|interfaceInterface}}) は、[[Java]]や[[C Sharp|C#]]などの[[オブジェクト指向プログラミング言語]]においてサポートされる、実装を持たない[[抽象型]]のことである。これらの言語において、[[クラス (コンピュータ)|クラス]]は実装の[[多重継承]]をサポートしない代わりに、任意の数のインタフェースを実装 (implement) することができ、これにより型の多重継承をサポートする。複数の種類の[[オブジェクト (プログラミング)|オブジェクト]]を、インタフェースを用いた[[多態性]]によって統一的に扱うことができるようになる。'''インターフェス'''などと表記することもある<ref>例えば[[オラクル (企業)|オラクル]]の日本語ドキュメントでは「インタフェース」と表記されているが、[[マイクロソフト]]の日本語ドキュメントでは「インターフェイス」と表記されている。本記事では「インタフェース」で統一するものとする。</ref>、主に[[オブジェクト指向プログラミング言語|オブジェクト指向言語]]で用いられている、実装と分離された[[抽象型]]の一種である。抽象化されたプログラムの動作・振る舞い(behavior)を扱うための手法である。[[統一モデリング言語|UML]][[クラス図]]の実現(realization)・実装(implementation)の関係に投影されたことで、OOPで重要視されるようになっている。より公式的にはプロトコル(Protocol)とも呼ばれ、それは[[関数型プログラミング|関数型]]のモジュールシグネチャ(signature)や[[手続き型プログラミング|手続き型]]のモジュール仕様書(specification)などを包括している
 
インターフェースの基本形は[[関数プロトタイプ|メソッドシグネチャ]]の集合体であり、概ね以下の項目で構成される。
 
# インターフェース名。{{仮リンク|記名的型付け|en|Nominal type system}}での識別を前提にしている。
# 「リターン型+メソッド名+パラメータリスト」の[[メソッド (計算機科学)|メソッド]]定義。メソッド実装([[コードブロック]])は除外される。
# 各メソッドからスローされる[[例外処理|例外クラス]]の宣言。
# 専用の[[定数 (プログラミング)|定数]]。
 
インターフェースの使用は[[Java]]や[[C Sharp|C#]]が有名であり、それらの言語では、メソッド実装=実装継承の[[多重継承]]をサポートしない代わりに、メソッド定義集合=純粋な界面継承の[[多重継承]]をサポートすることにしている。純粋な界面継承を表現する機能がインターフェースになった。インターフェース型の[[変数 (プログラミング)|変数]]には、その実装が宣言された各[[クラス (コンピュータ)|クラス]]の[[インスタンス]]が代入されて、どれが代入されるかは実行時に決定される。これは変数の[[サブタイピング]]の[[ポリモーフィズム]]になり、多様な[[オブジェクト (プログラミング)|オブジェクト]]を一つのインターフェースで扱える効用がある。
 
== 概要 ==
オブジェクト指向プログラミングにおいて、[[多重継承]]はプログラミングの自由度と柔軟性を向上する。[[C++]]は「実装の多重継承」をサポートし、クラスは複数の[[スーパークラス (計算機科学)|スーパークラス]](基底クラス)を持つことができる。しかし、実装の多重継承は[[菱形継承問題]]などの欠点を抱えている。実装の多重継承の問題点を回避するためにC++は[[仮想継承]]の仕組みを導入したが、これはプログラミング言語仕様が複雑化する原因となった。しかし、「型の多重継承」に限れば、問題点の多くは回避でき、また言語仕様もシンプルになる。JavaおよびC#では、実装の継承は単一継承に制限したうえで、代わりに具体的な実装を持たないインタフェースによる型の多重継承の仕組みを導入し、多重継承問題に対する解決策を提供している<ref>{{Cite web|url=https://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-JF18-Interfaces.pdf|title=進化するJavaインタフェース - Javaの多重継承を理解する -|author=Michael Kölling|accessdate=2019-02-24}}</ref>。
 
インタフェース自身はインスタンス化(実体化)することができないが、任意のクラスにてインタフェースを実装することで、そのクラスのインスタンスは当該インタフェースとして振る舞うことが可能となる。これは[[リスコフの置換原則]]に忠実な[[継承 (プログラミング)|継承]]の用法である。これは純粋な界面継承と(interface inheritance)と言われる。UML[[クラス図]]では実装(implementation)の関係に投影されている。90年代OOPの原則セット[[GRASP]]では保護的変容(protected variations)に該当される
 
JavaおよびC#では、抽象[[メソッド (計算機科学)|メソッド]](実装を持たないメソッド宣言)を持ち、実体化できないクラス(抽象クラス)を定義することも可能であるが、抽象クラスは実装を持つことも可能であり、インタフェースと違って多重継承することはできない。こちらは界面継承と実装継承(implementation inheritance)の混合になる。UMLクラス図では特化(specification)の関係に投影されている。[[GRASP]]では多態性(polymorphism)に該当される
 
インターフェースは、2000年代OOPの原則セット[[SOLID]]で特に重視されるようになっている。[[依存性逆転の原則]]では、[[Mixin|Mix-in]]の作法をインターフェースの用法に適用しており、Mix-inでの[[トレイト]]の役割を持たせたインターフェースを、機能提供の依存対象としてクラスに結合(注入)するデザインパターンが提唱されている。GRASPはこれを純粋造形(pure fabrication)として予告提唱していた。その際のインターフェースは、[[ドメイン駆動設計]]のサービスに相当するものになる。
JavaおよびC#では、抽象[[メソッド (計算機科学)|メソッド]](実装を持たないメソッド宣言)を持ち、実体化できないクラス(抽象クラス)を定義することも可能であるが、抽象クラスは実装を持つことも可能であり、インタフェースと違って多重継承することはできない。
 
== Java ==
86 ⟶ 97行目:
また、C#では<code>Guid</code>属性(<code>System.Runtime.InteropServices.GuidAttribute</code>クラス)により、インタフェースやクラスに[[GUID]]を付加することができる。[[.NET Framework]]のインタフェースやクラスを含む[[アセンブリ (共通言語基盤)|アセンブリ]]をCOMコンポーネントとして公開し、C++ネイティブコードや[[VBScript]]/[[JScript]]といった従来のCOM/[[Object Linking and Embedding|OLE]]対応言語などから利用するCOM相互運用も可能である<ref>[https://docs.microsoft.com/ja-jp/dotnet/framework/interop/exposing-dotnet-components-to-com COM への .NET Framework コンポーネントの公開 | Microsoft Docs]</ref>。
 
== その他言語・技術とテクノロジ ==
C++ではpublicな純粋仮想関数および純粋仮想[[デストラクタ]]のみを持つクラス(あるいは[[構造体]])を定義することで、JavaやC#のインタフェースを模倣し、多重継承の欠点を回避することもできる。
 
96 ⟶ 107行目:
== 関連項目 ==
* [[抽象型]]
* [[クラス (コンピュポリモタ)フィズム]]
* [[継承 (プログラミサブタイピング)]]
*[[継承 (プログラミング)|継承]]
* [[インタフェース (情報技術)]]
*[[クラス (コンピュータ)|クラス]]
 
{{デフォルトソート:いんたふえいす}}