インタフェースの機能は「抽象クラスの強力版」と考えるといいでしょう。
というわけで、2つを比較してみましょう。
インタフェースは「10.1 インタフェースという「抽象クラスっぽいもの」のPrintInterfaceインタフェースとImplementedクラス、抽象クラスは「9.1 abstractクラスとabstractメソッド」のAbstractSuperクラスとConcreteSubクラスを例に見てみます。
インタフェースと抽象クラスが同じところ
まずはインタフェースと抽象クラスが同じ点を見てみましょう。
それは「抽象メソッドを持つことができる」という点です。
普通のクラスが持つことのできない、中身のないメソッド「抽象メソッド」を、インタフェースと抽象クラスは持つことができます。
この抽象メソッドを使うことで、インタフェースは実装クラスに、抽象クラスはサブクラスに、強制的にメソッドを作らせることができて、ポリモーフィズムを使って呼び出すことができるというわけです。
また、抽象メソッドを持つため、インスタンスが作れないという点も共通しています。インタフェースも抽象クラスも、参照型変数を作れるだけで、newでインスタンスを作ることはできません。
このように、インタフェースと抽象クラスの機能は非常に似ています。
インタフェースと抽象クラスが違うところ
インタフェースと抽象クラスは機能的に似ています。
ただ、書き方や用語がちょっと違います。
(1):抽象クラスの「class」はインタフェースでは「interface」を使用します。
(2):インタフェースには「フィールド」や「中身のあるメソッド」を書くことができません。抽象メソッドと、public static finalなフィールドのみです。
(3):抽象クラスはクラス・抽象メソッドの前にabstractを付けなければいけませんが、インタフェースは付けません。
(4):インタフェースは「継承」を「実装」と呼びます。また、「オーバーライド」を「実装」と呼びます。
(5):抽象クラスの「extends」はインタフェースでは「implements」を使用します。
(6):インタフェースの抽象メソッドは自動的に「public」が付くので、実装メソッドはpublicメソッドにします。
インタフェースと抽象クラスの違いは「キーワードの違い」や「用語の違い」というレベルがほとんどで、たとえば大きく書き方が違ったり、全然別物だったりはしません。
なので、抽象クラスから頭の中で置き換えれば問題ないでしょう。
インタフェースの特徴
上記のような「文法的な違い」以外に、インタフェースには以下の特徴があります。
・継承関係に縛られない:クラスは多重継承できませんが、インタフェースはそういう制約がまったくありません。クラスから継承しつつインタフェースを実装したり、複数のインタフェースを実装することが可能です。
・キャストが自由:クラスは「継承関係が明確な場合」のみキャストが可能ですが、インタフェースはどんなキャストをしてもコンパイルエラーになりません。ただし、実行時にキャストして、インスタンスがインタフェースを実装していなかったら例外が投げられます。
実はこの「インタフェースの特徴」こそが、クラスとインタフェースを分ける要因になっています。
一見、インタフェースは「抽象クラスの強力版」のように見えますが、もしそれだけだったら、わざわざインタフェースなんてものを作るはずがありません。しかも、わざわざ「interface」や「implements」といった新しいキーワードを作ってまで、です。
というわけで、次ページ以降はインタフェースのへんてこさを見ていくことにしましょう。