Udemy 「JavaSE8 インタフェース ラムダ式 ストリーム 集中コース」セクション3
セクション3 インタフェース
関数型インターフェース:SE8から追加された機能
関数型インターフェースの特徴
- 抽象メソッドは1個のみ
- インターフェースの名称と抽象メソッドの名称が1対1で対応している
- シグニチャ(戻り値と引数)によって処理内容の概要が決定される
- 関数型インターフェースのオブジェクト化を「抽象メソッドを実装する」方法で実現可能
レクチャー01 SE7までのインタフェースの特徴
- 複数個の抽象メソッドが設定可能
- 継承にて利用されるのが一般的
- 定数はpublic static扱いになる
- オブジェクトにはなれない
- ポリモフィズム実現の手段
- プログラミングよりも設計段階にて利用される
public interface Se7Interface { // 定数(public static は省略可。) public static int fromHeiseiYear = 1898; // 抽象メソッド(abstract は省略可。) abstract String getData(String data); abstract Integer getInteger(Integer integer); }
Se7Interfaceは抽象メソッドを複数持つため関数型インターフェースではない。
SE7→SE8の変更点:オプジェクトになることができる(new ~~Interface)
レクチャー02 SE8インターフェースの特徴
- 複数の静的(static)メソッドが設定可能
- 複数個のdefaultメソッドが設定可能
- 複数個の抽象メソッドが設定可能
(利用時:実装化か必須)
(再確認:関数型インターフェースの抽象メソッド数は1個
- new演算子によるオブジェクト生成が可能
- 関数型インターフェースはSE8インターフェースにおける一つの特殊な形態である。
レクチャー03 インターフェースのまとめ
レクチャー04 SE8を利用したサンプルプログラム
Java7までは匿名クラスを作るか、インターフェースを実装したクラスを作るしかなかった。
public interface SampleInterface { // 静的メソッド static void printStatic() { System.out.println("静的メソッド"); } // defaultメソッド default void printDefault() { System.out.println("Defaultメソッド"); } // 抽象メソッド abstract void printAbstract(String inStr); // 実装されているメソッド → コンパイルエラー // void printMethod() { // System.out.println("実装されているメソッド"); // } }
public class S03L04 { public static void main(String[] args) { // 静的メソッドはnewしなくても実行可能 SampleInterface.printStatic(); // 抽象メソッドが未オーバーライドなのでコンパイルエラー // SampleInterface si1 = new SampleInterface(){}; // 匿名クラスを用いたオブジェクト生成 SampleInterface si2 = new SampleInterface() { @Override public void printAbstract(String inStr) { System.out.println(inStr); } }; // defaultメソッドの実行 si2.printDefault(); // オーバーライドされたメソッドの実行 si2.printAbstract("オーバーライドされた抽象メソッド"); // S03L0402オブジェクトにて実行 S03L0402 s = new S03L0402(); s.printAbstract("オーバーライドされた抽象メソッド2"); } } class S03L0402 implements SampleInterface { @Override public void printAbstract(String inStr) { System.out.println(inStr); } }
レクチャー05 関数型インターフェース
@FunctionalInterface public interface CheckWonLottery { // 抽象メソッド abstract public String check(Integer inNnumber, Integer winNumber); }
[補足事項]
- @FunctionalInterface:関数型インタフェースを意味するアノテーション
- abstract:抽象メソッドを意味する、省略可能
- 静的メソッド、defaultメソッドの有無には捕らわれない
[構文解説]
シグニチャ:
引数:二個のInteger、戻り値:String
[関数型インタフェースの特徴]
CheckWonLotteryとcheck(抽象メソッド)が1対1に対応している
レクチャー06 関数型インタフェースのオブジェクト生成と利用方法
public class S03L06 { public static void main(String[] args) { CheckWonLottery cw = new CheckWonLottery() { @Override public String check(Integer n1, Integer n2) { if (n1 == n2) return "的中"; else return "外れ"; } }; String result = cw.check(10555, 105559); System.out.println(result); // 外れ } }
注意:
- check(Integer n1, Integer n2)で”int” のような基本型は使わないと覚えておく。
- “CheckWonLottery” のような特定の場合だけに使うような名前は避ける。より寛容的な名前をつけよう。
レクチャー07 SE8にて利用できる主な関数型インタフェース一覧
これらのインタフェースはJava8から組み込まれている。普通に使って良い。
それぞれのシグニチャはバラバラ。
新たな関数型インタフェースを作ることは稀。
適切なものを上記から選んで使うのが好ましい。
レクチャー08 関数型インタフェースJavaAPIドキュメントの参照方法
!!!!JavaAPIは見る癖をつけましょう!!!!!
Consumer インタフェースのAPI参照する。
andThenというメソッドがあるからどのような挙動か確認してみる。
import java.util.function.Consumer; public class S03L08 { public static void main(String[] args) { // 構文:abstract void accept(T t) Consumer<String> cs1 = new Consumer<String>() { @Override public void accept(String inStr) { System.out.println("cs1" + inStr); } }; cs1.accept("の実行"); Consumer<String> cs2 = new Consumer<String>() { @Override public void accept(String inStr) { System.out.println("cs2" + inStr); } }; cs2.accept("の実行"); Consumer<String> cs3 = cs1.andThen(cs2); System.out.println("以下、cs3の実行結果"); cs3.accept("の実行"); // cs1とcs2のオブジェクトが連続実行 } }
次回から今まで書いた匿名クラスをラムダ式に変換していく。