M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

Java8で導入されたdefaultメソッドについてメモ

Javaプログラミング言語の拡張機能を読む限りだいたいこんな感じでしょうか:

基本ルール

  • defaultキーワードを持つメソッドは実装を持つ。持たねばならない。
  • defaultキーワードを持つメソッドは同一インターフェースにいくつでも持たせることができる。
  • 宣言されたメソッドが1つしかないインターフェースに@FunctionalInterfaceを付与しておくことで、そのアノテーションが維持されている限り、メソッド宣言が誤って追加されたときにコンパイル・エラーにより検知できる。だから付与すべきである。
  • @FunctionalInterfaceの「宣言されているメソッドは1つだけ」という制約にdefaultメソッドは数えられない。
  • defaultメソッド複数持っていても実装を持たないメソッドが1つであればラムダ式で使用できる(ラムダ式により匿名インナークラスとしてそのインターフェースを実装できる)。

継承ルール

  • サブ・インターフェースでdefaultキーワードなしで同一シグネチャメソッドを再宣言するとabstractメソッドになる。ただしインターフェースなのでabstractメソッドについて明示的なキーワード指定は不要。
  • サブ・インターフェースでdefaultキーワードありで同一シグネチャメソッドを再宣言するとdefaultメソッドによるオーバーライドとなる(まあ当たり前)。

多重継承

  • 具象クラス(abstractでないクラス)で同一シグネチャdefaultメソッドを持つ複数のインターフェースをimplements句に列挙する場合、具象メソッドによりオーバーライドしなくてはならない。たとえ内容的には列挙したインターフェースのうち1つのdefaultメソッドを呼び出すだけであっても(記法は後述)、オーバーライドは必須。つまり「宣言の順番でいずれのdefaultメソッドが使用されるか決まる」というような宣言的ルールは存在しない。個別のメソッドのレベルで見たとき、実行されるコードはプログラマブルに一意に決定されるということ。
  • このときインターフェースに宣言されたdefaultメソッドのいずれかを呼出すためには「インターフェース名.super.メソッド名(引数...)」という書式を使う。つまり多重継承では明示的な委譲によってしかdefaultメソッドはコールされない。繰り返しになるが、個別のメソッドのレベルで見たとき、実行されるコードはプログラマブルに一意に決定されるということ。
  • 抽象クラスで同一シグネチャdefaultメソッドを持つ複数のインターフェースをimplements句に列挙する場合、abstractキーワードを使い明示的に実装を持たないメソッド宣言で上書きするか、さもなくばabstractdefaultもない具象メソッドによりオーバーライドするしかない。
  • インターフェースで同一シグネチャdefaultメソッドを持つ複数のインターフェースをextends句に宣言する場合、明示的に実装を持たないメソッド宣言で上書きするか(abstractはあってもなくてもよい)、さもなくばdefaultキーワードと実装を持つメソッドでオーバーライドするしかない。
  • インターフェースにしろ抽象・具象クラスにしろ、メソッド名と引数が同一であっても戻り値が異なるdefaultメソッドを持つインターフェースを拡張することはできない(defaultメソッドに限らずもともと不可能なはなし)。