インタフェース (抽象型)

出典: フリー百科事典『ウィキペディア(Wikipedia)』

出典: フリー百科事典『ウィキペディア(Wikipedia)』

インタフェース (: interface) は、JavaC#などのオブジェクト指向プログラミング言語においてサポートされる、実装を持たない抽象型のことである。これらの言語において、クラスは実装の多重継承をサポートしない代わりに、任意の数のインタフェースを実装 (implement) することができ、これにより型の多重継承をサポートする。複数の種類のオブジェクトを、インタフェースを用いた多態性によって統一的に扱うことができるようになる。インターフェイスなどと表記することもある[1]

概要[編集]

オブジェクト指向プログラミングにおいて、多重継承はプログラミングの自由度と柔軟性を向上する。C++は「実装の多重継承」をサポートし、クラスは複数のスーパークラス(基底クラス)を持つことができる。しかし、実装の多重継承は菱形継承問題などの欠点を抱えている。実装の多重継承の問題点を回避するためにC++は仮想継承の仕組みを導入したが、これはプログラミング言語仕様が複雑化する原因となった。しかし、「型の多重継承」に限れば、問題点の多くは回避でき、また言語仕様もシンプルになる。JavaおよびC#では、実装の継承は単一継承に制限したうえで、代わりに具体的な実装を持たないインタフェースによる型の多重継承の仕組みを導入し、多重継承問題に対する解決策を提供している[2]

インタフェース自身はインスタンス化(実体化)することができないが、任意のクラスにてインタフェースを実装することで、そのクラスのインスタンスは当該インタフェースとして振る舞うことが可能となる(リスコフの置換原則)。

JavaおよびC#では、抽象メソッド(実装を持たないメソッド宣言)を持ち、実体化できないクラス(抽象クラス)を定義することも可能であるが、抽象クラスは実装を持つことも可能であり、インタフェースと違って多重継承することはできない。

Java[編集]

Javaのインタフェースは、暗黙的にpublicな抽象メソッドのみを持つことが許される参照型である。定数および入れ子になった型の定義は許される。Javaではクラスの継承にextendsキーワードを使用するが、インタフェースの実装にはimplementsキーワードを使用する。インタフェースを拡張して新たなインタフェースを派生させるときはextendsキーワードを使う。

// 捕食動物を表すインタフェース
public interface Predator {
    boolean chasePrey(Prey p); // 餌を追いかける
    void eatPrey(Prey p); // 餌を食べる
}

public class Cat implements Predator {

    public boolean chasePrey(Prey p) {
        // chasePrey メソッドの実装
    }

    public void eatPrey(Prey p) {
        // eatPrey メソッドの実装
    }
}

Javaの列挙型は抽象クラスjava.lang.Enumから暗黙的に派生する参照型であり、任意のインタフェースを実装することができる。

なお、Java 8以降ではインタフェースのデフォルトメソッドにより、実装の多重継承も限定的にサポートするようになった。また、インタフェースが静的メソッドを持つこともできるようになった[3]。Java 8で導入されたラムダ式およびメソッド参照は、実装すべきメソッドをひとつだけ持つ「関数型インタフェース」(functional interface) によって実現されている。

C#[編集]

C#のインタフェースは、概ねJava同様であり、暗黙的にpublicな抽象メソッド、抽象プロパティ、抽象インデクサのみを持つことが許される参照型である。ただし、定数および入れ子になった型の定義は許されない。インタフェース名はIで始めることが推奨されている。

C#の構造体は抽象クラスSystem.ValueTypeから暗黙的に派生する値型であり、基底クラスを明示的に指定することはできないが、任意のインタフェースを実装することはできる。C#の列挙型は抽象クラスSystem.Enumから暗黙的に派生する値型であるが、構造体とは違って任意のインタフェースを実装することはできない。構造体および列挙型のインスタンスは、実装されたインタフェース型の変数に暗黙的に代入できるが、型変換(キャスト)の際にボックス化が発生する。

usingステートメントで使用できるSystem.IDisposableのように、構文上特別扱いされるようになるインタフェース型もある。

その他の言語・技術[編集]

C++ではpublicな純粋仮想関数および純粋仮想デストラクタのみを持つクラス(あるいは構造体)を定義することで、JavaやC#のインタフェースを模倣し、多重継承の欠点を回避することもできる。

マイクロソフトComponent Object Model (COM) は、プログラミング言語を問わず再利用可能なソフトウェアコンポーネントを作成するために用いられる技術であり、COMインタフェースはIUnknown派生の実装を持たない抽象型として、COMサーバーとCOMクライアントをつなぐ役割を果たす。COMの思想や概念はのちに.NET FrameworkWindowsランタイムにも受け継がれることになった。

脚注・出典[編集]

  1. ^ 例えばオラクルの日本語ドキュメントでは「インタフェース」と表記されているが、マイクロソフトの日本語ドキュメントでは「インターフェイス」と表記されている。本記事では「インタフェース」で統一するものとする。
  2. ^ Michael Kölling. “進化するJavaインタフェース - Javaの多重継承を理解する -”. 2019年2月24日閲覧。
  3. ^ Default Methods (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance)

関連項目[編集]