Java -抽象クラス・インタフェース-
抽象クラスと抽象メソッド
抽象メソッドを1つ以上持つクラスを抽象クラスといいます。
抽象メソッドが1つでもあれば、そのクラスのclassキーワードの前にabstract修飾子を付ける 必要があります。省略はできません。
抽象クラスでは、抽象メソッドのコードが未定義になっていますので、ポリモフィズムの実現が容易です。
抽象メソッドとは、メソッドの仕様の部分(アクセス修飾子、戻り値の型、メソッド名、引数の型、引数の数、引数の型の並び順、throwsによって投げられる例外クラス)だけが記述されていて、コードを実装するブロックがないもののことです。
抽象メソッドにもabstract修飾子が必要です。省略できません。
[public] abstract class クラス名{…}
※ []は省略可能
[修飾子] abstract 戻り値の型 メソッド名([引数の型 引数名][,…]);
※ []は省略可能
※ 抽象メソッドの最後はセミコロン(;)を忘れないようにします。
※ コードを実装するブロック{}があるとコンパイルエラーになります。
- 抽象クラス内の抽象メソッドは、抽象クラスをスーパークラスとするサブクラスで必ず、オーバーライドしなければなりません。
- 抽象クラスは、抽象メソッドを持つこと以外は通常のクラスと同じです。
したがって、複数のメンバ変数や複数の通常のメソッド(具象メソッド)を持つことができます。 - 抽象クラスには、抽象メソッドという実装部分のないメソッドが存在するため、このクラスからインスタンスの生成をすることはできません。
抽象クラスによるポリモフィズムの実現
抽象クラスは、通常クラス(具象クラス)のスーパークラスとして利用されます。
つまり、継承によるポリモフィズムと同様の処理が抽象クラスを利用した場合も行うことができます。
インタフェース
抽象クラスは、一部に抽象メソッドを含むというクラスのことでしたが、インタフェースはインタフェースは仕様と定数だけで構成され、具体的なコード部分をいっさい含まないため、抽象クラスよりもさらに自由なポリモフィズムが可能になります。
インタフェース内に定義したメンバ変数には、暗黙的にpublic abstractという修飾子が付き、抽象メソッドとなります。
インタフェースで定義された抽象メソッドをクラス内で実装するには、implementsキーワードを使います。
スーパークラスが1つしか定義できないのに比べ、インタフェースは複数のインタフェースを実装(多重実装)することができます。
interface インタフェース名{…}
class クラス名 implements インタフェース名1 [,インタフェース名2…]{…}
※ []省略可能
オーバーライド時のアクセス制御指定
インタフェースで指定した抽象メソッドは、必ず、通常のクラス(具象クラス)内でオーバーライドをしなければなりません。
オーバーライドの際にはアクセス修飾子は、インタフェースで指定したメソッドのアクセス制御と同じか、より緩いアクセス修飾子を指定しなければなりません。
インタフェースの継承
インタフェースが別のインタフェースを継承することができます。
クラスの継承とは異なり、複数のインタフェースを同時に継承することが可能です。
継承には、extendsキーワードを利用します。
[修飾子] interface インタフェース1 extends インタフェース2[,インタフェース3…]{…}
※ []省略可能
インタフェースによるポリモフィズムの実現
通常の継承によるポリモフィズムの実現も、抽象クラスを利用したポリモフィズムの実現も、スーパークラス(抽象クラス)サブクラスの継承関係がなければ利用することはできません。
しかし、インタフェースを利用する場合は、それぞれのクラスの属性や操作の共通部分がほとんど存在していなくても、インタフェースの実装さえ行っていればポリモフィズムが実現できるというメリットがあります。
インタフェースや抽象クラスの組み合わせ
組み合わせの規則
- インタフェースは、他の複数のインタフェースを同時に継承できます。
しかし、他の抽象クラスや具象クラスを継承または、実装することはできません。 - 抽象クラスは、他の具象クラスや抽象クラスを継承できます。
ただし、継承できるクラスは、1つだけです。
抽象クラスは、複数のインタフェースの実装ができます。
ただし、継承や実装した抽象メソッドは、このクラスでオーバーライドしなくても構いません。 - 具象クラスは、他の具象クラスや抽象クラスを継承できます。
ただし、継承できるクラスは、1つだけです。
また、具象クラスは、複数のインタフェースを実装できます。
ただし、継承や実装した抽象メソッドは、必ずこのクラスでオーバーライドしなければなりません。