インターフェイスとは、実装の無いpublicな抽象メソッドで構成されたものです。
インターフェイスは、publicメソッドを定義しますが、機能を実装しません。
ただし、フィールド(固定値のみ)、メソッド名、メソッドの引数と型、戻り値は定義します。
インターフェイスには、3つの役割を持ちます。
1.のケースで作成するクラスはインターフェイスと明確に区別するために接尾語に「Impl」を付与します。
これは、「implements(実装)」の略です。
implements
インターフェイス1,
インターフェイス2
Web3階層システムにおいてインターフェイスを利用する事例です。1.公開するクラスの仕様の確定のサンプルになります。
Web3階層システムにおいて、エンジニアは、プレゼンテーション(主に画面)とビジネスロジック(Service)とデータ(Dao)で分業します。
プレゼンテーション層を担当するエンジニアは、ビジネスロジック以下の詳細は深く知る必要はありません。
知っておくべきことは、ビジネスロジック層のサービスクラスがどのような機能があるかです。
そして、その機能の概要と入力引数、戻り値の仕様を理解していおけばよいのです。
対して、ビジネスロジックとデータ層を作成するエンジニアは、サービスの機能の概要と入力引数、戻り値を設計書に従い公開します。
インターフェイスは、公開した仕様なので一度決めた引数、メソッド名、戻り値を勝手に変更してはいけません。
変更する場合には、チームにアナウンスしてインターフェイスの変更を相談して確定します。
このようにインターフェイスは、実装(implements)するクラスにインターフェイスに定義したメソッドの実装を強制します。
ECサイトで買い物カゴに商品を入れて購入手続きを実行することを想像して下さい。
ECサイトでは、利用者に多くの商品を購買して頂くために買い物カゴ機能が存在します。
買い物カゴに入れた商品は、買い物カゴに入れた日に購入しなくても、データベースに保存されます。
そして、給料日後に実際に購入手続きだけをした場合に必ず次のチェック(ビジネスロジック)が実行されます。
買い物カゴに入れた時の商品の値段と現在の商品の値段が異なったり、在庫有無をチェックしたりと多くのチェック処理を実施します。
上記UMLのように、OrderServiceインターフェイスがcheckOrderメソッドを定義しているので、
OrderServiceインターフェイス実装したクラスOrderSeviceImplクラスは、checkOrderメソッドを実装しているのです。
OrderServcie.java
/**
* Copyright 2017 yourcompany.
* 本ソースファイルの著作権は株式会社yourcompanyに所属します。
* 株式会社yourcompanyの許可なくして、本ソースファイルの
* 配布、改修、コピー、利用を禁止します。
* 会社名 :株式会社yourcompany
* 組織名 :システム開発部
* プロジェクトコード :education
* バージョン :1.0
* 最終更新日時 :2017/03/07 20:00
*/
package jp.co.yourcompany.education.order.service;
import java.util.List;
import jp.co.yourcompany.education.order.dto.OrderCartItem;
import jp.co.yourcompany.education.order.dto.OrderCheckResult;
/**
* インターフェイスを理解するための
* サンプルインターフェイス
* @author raita.kuwabara
*
*/
public interface OrderService {
/**
* このサービスのサブシステムコード
*/
public static final String SUBSYSTEM_CODE = "order";
/**
* カートに指定された商品の在庫数や購入価格と現在価格の差異のチェックなど
* 購入者に警告メッセージが必要な商品の警告を返すサービス
* @param itemList 買い物カゴの商品リスト
* @return 警告リスト サイズが0の場合には、警告なし
*/
public List<OrderCheckResult> checkOrder( List<OrderCartItem> itemList);
}
OrderServcieImpl.java抜粋
//コメント割愛
package jp.co.yourcompany.education.order.service;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import jp.co.yourcompany.education.order.dto.OrderCartItem;
import jp.co.yourcompany.education.order.dto.OrderCheckResult;
/**
* 注文サービス
* @author raita.kuwabara
*/
public class OrderServiceImpl implements OrderService {
/**
* 買い物カゴの商品をチェックし、チェックした結果を返す。
* @param itemList カート商品のリスト
* @return resultList 商品チェック結果 配列数0の場合には、警告なし。
*/
@Override
public List<OrderCheckResult> checkOrder(List<OrderCartItem> itemList) {
List<OrderCheckResult> resultList = new ArrayList<OrderCheckResult>();
for( OrderCartItem cartItem : itemList ) {
OrderCheckResult checkResult = null;
checkResult = checkDifferencePrice( cartItem );
if( checkResult != null){
resultList.add( checkResult );
}
checkResult = checkStock( cartItem );
if( checkResult != null){
resultList.add( checkResult );
}
}
return resultList;
}
implementsした子クラスがメソッドを実装する場合には、@Overrideアノテーションをメソッド定義前行に宣言します。
@Override
多様性でも詳しく説明いたします。
次のサンプルは、「2.JavaAPIの特化した機能の定義」「3.複数の機能を明示化」の例を説明します。
上記UMLでは、買い物カゴの商品情報を保存するDtoオブジェクトです。
OrderクラスのimplementsをみるとClonableとSerializableを利用しています。
Clonableインターフェイスはオブジェクトのコピー機能に特化したインターフェイスです。
Clonableインターフェイスをimplementsしたクラスはclone()メソッドに
オブジェクトのコピー内容を実装することで、オブジェクトのコピー機能が実現できます。
Serializableインターフェイスはオブジェクトを出力ストリームに書き出せる機能です。(シリアライズ)
Serializableは、シリアライズしたいDtoオブジェクトにimplmentsするだけでそのオブジェクトがシリアライズできるオブジェクトになります。
以上より、Orderクラスは、「コピー機能」「シリアライズ機能」を持つDtoとなります。
Order.java抜粋
import java.io.Serializable;
public class Order implements Cloneable ,Serializable {
/**
* オブジェクトのコピーを取得する。
*/
@Override
public Order clone() {
Order copyObj = null;
try {
copyObj = ( Order ) super.clone();
//ディープコピー オブジェクト型は明示しないと同じインスタンスを指してしまう。
copyObj.setOrderDate( new java.util.Date( this.getOrderDate().getTime() ) );
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copyObj;
}
//他メソッド割愛
}
OrderCartItem.java抜粋
public class OrderCartItem extends Order {
/**
* オブジェクトのコピー
*/
@Override
public OrderCartItem clone(){
OrderCartItem copyObj = null;
copyObj = ( OrderCartItem ) super.clone();
copyObj.setDateInCart( new java.util.Date ( this.getDateInCart().getTime() ) );
return copyObj;
//他メソッド割愛
}
}
インターフェイスは、理屈で覚えるのではなく多くの一流ソースを見て、多くのソースを記述することで使いどころが身に付きます。
JavaAPIには、各種機能を実現させるためのインターフェイスが多く提供されています。
実装するときにJavaAPIを確認して、これはinterfaceだからimplementsするときに公開されたメソッドを実装しなくてはならないなと
それだけを覚えていれば良いだけです。細かい機能の実装はJavaAPIや本サイトなどの技術サイトで確認すれば良いのです。