Java8で導入されたdefaultメソッドについてメモ
Javaプログラミング言語の拡張機能を読む限りだいたいこんな感じでしょうか:
基本ルール
default
キーワードを持つメソッドは実装を持つ。持たねばならない。default
キーワードを持つメソッドは同一インターフェースにいくつでも持たせることができる。- 宣言されたメソッドが1つしかないインターフェースに
@FunctionalInterface
を付与しておくことで、そのアノテーションが維持されている限り、メソッド宣言が誤って追加されたときにコンパイル・エラーにより検知できる。だから付与すべきである。 @FunctionalInterface
の「宣言されているメソッドは1つだけ」という制約にdefault
メソッドは数えられない。default
メソッドを複数持っていても実装を持たないメソッドが1つであればラムダ式で使用できる(ラムダ式により匿名インナークラスとしてそのインターフェースを実装できる)。
継承ルール
多重継承
- 具象クラス(
abstract
でないクラス)で同一シグネチャのdefault
メソッドを持つ複数のインターフェースをimplements
句に列挙する場合、具象メソッドによりオーバーライドしなくてはならない。たとえ内容的には列挙したインターフェースのうち1つのdefault
メソッドを呼び出すだけであっても(記法は後述)、オーバーライドは必須。つまり「宣言の順番でいずれのdefault
メソッドが使用されるか決まる」というような宣言的ルールは存在しない。個別のメソッドのレベルで見たとき、実行されるコードはプログラマブルに一意に決定されるということ。 - このときインターフェースに宣言された
default
メソッドのいずれかを呼出すためには「インターフェース名.super.メソッド名(引数...)
」という書式を使う。つまり多重継承では明示的な委譲によってしかdefault
メソッドはコールされない。繰り返しになるが、個別のメソッドのレベルで見たとき、実行されるコードはプログラマブルに一意に決定されるということ。 - 抽象クラスで同一シグネチャの
default
メソッドを持つ複数のインターフェースをimplements
句に列挙する場合、abstract
キーワードを使い明示的に実装を持たないメソッド宣言で上書きするか、さもなくばabstract
もdefault
もない具象メソッドによりオーバーライドするしかない。 - インターフェースで同一シグネチャの
default
メソッドを持つ複数のインターフェースをextends
句に宣言する場合、明示的に実装を持たないメソッド宣言で上書きするか(abstract
はあってもなくてもよい)、さもなくばdefault
キーワードと実装を持つメソッドでオーバーライドするしかない。 - インターフェースにしろ抽象・具象クラスにしろ、メソッド名と引数が同一であっても戻り値が異なる
default
メソッドを持つインターフェースを拡張することはできない(default
メソッドに限らずもともと不可能なはなし)。