JavaSE8以降のインタフェースについて
JavaSE7以前のインタフェースとJavaSE8以降のインタフェースの使用がだいぶ違うのでメモ。
JavaSE7までのインタフェースの特徴
- 複数個の抽象メソッドが設定可能
- 継承で利用されるのが一般的
- 定数はpublic static 扱いになる
- オブジェクトになれない
JavaSE8のインタフェースの特徴
- 複数個の静的メソッドが設定可能
- 複数個のdefaultメソッドが設定可能
- 複数個の抽象メソッドが設定可能
- new 演算子によるオブジェクト生成が可能
関数型インタフェースの特徴
- 抽象メソッド数は1個のみ
- インタフェースの名称と抽象メソッドの名称が1対1で対応している
- シグニチャ(戻り値と引数)によって処理内容の概要が決定される
- 関数型インタフェースのオブジェクト化を抽象メソッドを実装する方法で実現可能
関数型インタフェースはJavaSE8インタフェースの形態の一つ。\ 関数型インタフェースと内部の抽象メソッドは1対1で対応している。
インタフェースまとめ
SE7インタフェース | SE8インタフェース | SE8関数型インタフェース | |
---|---|---|---|
抽象メソッド | 複数設定可 | 複数設定可 | 1個のみ |
静的メソッド | 設定不可 | 複数設定可 | 複数設定可 |
defaultメソッド | 設定不可 | 複数設定可 | 複数設定可 |
オブジェクト生成 | 生成不可 | 生成可 | 生成可 |
SE8のインタフェース実装例
package sample; public interface SampleInterface { static void printStatic() { System.out.println("静的メソッド"); } default void printDefault() { System.out.println("Defaultメソッド"); } // 抽象メソッド abstract void printAbstract(String inStr); }
SE8のインタフェースは、以下のようにインスタンス化できる。
package sample; public class Sample { public static void main(String[] args) { // 静的メソッドの実行 SampleInterface.printStatic(); // 抽象メソッドの実装とインスタンス化(匿名クラスを new してる) // → インターフェースを継承した名前の無いクラスを new SampleInterface si = new SampleInterface() { @Override public void printAbstract(String inStr) { System.out.println(inStr); } }; // オーバーライドしたメソッドの実行 si.printAbstract("オーバーライドされた抽象メソッド"); // defaultメソッドの実行 si.printDefault(); } }
関数型インタフェース
package sample2; @FunctionalInterface public interface CheckWonLottery { // 抽象メソッド abstract public String check(Integer inNumber, Integer winNumber); }
package sample2; public class Sample { public static void main(String[] args) { // n1 : くじの番号、n2 : 当選番号 // 匿名クラスの作成 CheckWonLottery cw = new CheckWonLottery() { @Override public String check(Integer n1, Integer n2) { if (n1 == n2) { return "的中"; } else { return "ハズレ"; } } }; String result = cw.check(105555, 1055559); System.out.println(result); } }
関数型インタフェースの一覧(よく使うものだけ)
関数型インタフェース名 | 抽象メソッド構文 | 概要 |
---|---|---|
Function<T, R> |
R apply(T t) | 引数:T 戻り値:R |
Consumer<T> |
void accept(T t) | 引数:T 戻り値:なし |
Predicate<T> |
boolean test(T t) | 引数:T 戻り値:boolean |
Supplier<T> |
T get() | 引数:なし 戻り値:T |
UnaryOperator<T> |
T apply(T t) | 引数:T 戻り値:T |
BinaryOperator<T> |
T apply(T t1, T t2) | 引数:T(2個) 戻り値:T |
BiFunction<T, U, R> |
R apply(T t, U u) | 引数:T、U 戻り値:R |
既に定義されているものは後で定義してはならない。 というより、たくさんあるので使用用途に当てはまるものがあることが多く、自分で作ることはない。