Java8でのラムダの使い方などを説明してきたのですが、構文拡張自体には触れていなかったので、改めてここで簡単に説明しておこうと思います。
まずは、Java8で実際に最もインパクトがある言語拡張、インタフェースのデフォルトメソッドです。
デフォルトメソッドとデフォルト実装
いままでインタフェースには実装をもつことができませんでしたが、Java 8からはインタフェースが実装をもてるようになります。
実装をもつメソッドを定義するときには、キーワードdefaultをメソッドの前につけます。
interface Foo{ void print(String s); default void twice(String s){ print(s); print(s); } }
twiceメソッドが実装をもっています。この実装をデフォルト実装といいます。
デフォルトメソッドを実装するクラスで、デフォルトメソッドを実装していない場合は、デフォルト実装が使われます。
static class FooImpl implements Foo{ @Override public void print(String s) { System.out.println(s); } }
次のtwiceメソッドの呼び出しでは、Fooインタフェースでのデフォルト実装が使われます。
public static void main(String... args){ Foo f = new FooImpl(); f.twice("yeah!"); }
ただし、toStringなどObjectクラスがもつメソッドのデフォルト実装をもつことはできません。
デフォルトメソッドでの多重継承
デフォルトメソッドは、Javaに多重継承を持ち込みます。
インタフェースは複数のインタフェースを継承することができ、またクラスでは複数のインタフェースを実装することができます。そうすると、インタフェースが実装をもつことによって、複数のインタフェースで同じシグネチャのメソッドがあったときに衝突が発生します。
たとえば、次のようにtwiceというデフォルトメソッドをもったインタフェースがあるとします。
interface Bar{ void put(String s); default void twice(String s){ put(s + s); } }
単体での実装は問題ありません。
static class BarImpl implements Bar{ @Override public void put(String s) { System.out.println(s); } }
次のように呼び出すことができます。
Bar b = new BarImpl(); b.twice("ゴゴ");
ところが、次のように、それぞれデフォルトメソッドとしてtwiceメソッドを持ったFoo、Barインタフェースを両方実装するクラスを定義しようとすると、コンパイルエラーになります。
static class FooBarImpl implements Foo, Bar{ @Override public void print(String s) { System.out.println(s); } @Override public void put(String s) { System.out.println(s); } }
次のようなコンパイルエラーになります。
この場合、改めてデフォルトメソッドを実装してしまえば、問題なくコンパイルすることができます。どちらかのインタフェースのデフォルト実装を利用したい場合は、キーワードsuperを使ってインタフェースを指定したデフォルト実装を呼び出すことができます。
static class FooBarImpl implements Foo, Bar{ @Override public void print(String s) { System.out.println(s); } @Override public void put(String s) { System.out.println(s); } @Override public void twice(String s){ Bar.super.twice(s); } }
抽象クラスとの違い
2013/6/23 追記
インタフェースが実装をもてることで、抽象クラスとの違いがあまりなくなってきました。
簡単に両者の違いをまとめると次のようになります。
インタフェース:多重継承できる。状態をもてない。
抽象クラス:多重継承できない。状態をもてる。
- 作者: 櫻庭祐一
- 出版社/メーカー: 技術評論社
- 発売日: 2015/11/19
- メディア: Kindle版
- この商品を含むブログ (2件) を見る