スレッドなどでよく登場するJavaのInterface(インターフェース)を解説したいと思います。呪文のようにimplementsを書いている人にも、意味をわかって貰えれば嬉しいです。
スレッドで使うimplementsの意味を理解したい
Javaでコードを書いていると、稀にインターフェースを実装(implements)したクラスを作ることがあると思います。
例えば、以下の記事で紹介したスレッドを実装する時など。
取り敢えず呪文のようにimplemetsを書いて、スレッドであれば言われた通りのrun()メソッドを実装すればいいんですが、せっかくなので意味を理解したいですよね。
implementsではインターフェースというクラスの型を実装する
Javaではインターフェースというクラスの型を定義するための仕組みを使うことができます。
このインターフェースを実装して作ったクラスは、必ずインターフェースに記載されたメソッドを実装しなくてはいけない、という決まりになっています。
例えば、以下のようなRobotInterface を実装したクラスは、runメソッドを実装しないとコンパイルが通らなかったり、IDE(統合開発環境・エディタ)に怒られます。
public interface RobotInterface { // 起動する void run(); }
下の画面はIDEに怒られる図です。
インターフェースでは定数とメソッドの定義だけを行う
インターフェースには、定数とメソッドの定義だけを行い、具合的な処理の内容は記載しません。
複数のインターフェースを実装することができる
継承(extends)と違って、インターフェースは複数実装(implements)することができます。
インターフェースは何のためにあるのか?
オブジェクト志向の三大要素の一つであるポリモーフィズム(多態性)を実現するためです。
ポリモーフィズムとは、類似したクラスに送るメッセージを共通化する仕組みです。
例えば、挨拶する(greet)というメッセージを、アメリカ人、日本人、中国人に送ると、
- アメリカ人は「Hello」
- 日本人は「こんにちは」
- 中国人は「ニーハオ」
と応える、と言った具合です。
類似したクラスに共通したメソッドを定義するが、ふるまいは変えたい、という場合にポリモーフィズムの概念が必要とされ、インターフェースを使って実現します。
サンプルプログラム
料理用のCookingインターフェースと、ロボット用のRobotインターフェースを2つ定義して、料理ロボットのCookingRobotクラスを作って動かしてみます。
料理用Cookingインターフェース
public interface CookingInterface { // 切る void cut(); // 焼く void bake(); }
Robotインターフェース
public interface RobotInterface { // 定数 String greeting_message = "こんにちは。ロボットを起動しました"; // 起動する void run(); }
2つのインターフェースを実装したCookingRobotインターフェース
public class CookingRobot implements CookingInterface, RobotInterface{ @Override public void cut() { System.out.println("切ってます"); } @Override public void bake() { System.out.println("焼いてます"); } @Override public void run() { System.out.println(greeting_message); this.cut(); this.bake(); } }
実行用メインメソッド RobotManager
public class RobotManager { public static void main(String[] args){ CookingRobot cook_robo = new CookingRobot(); cook_robo.run(); } }
実行
RobotManagerを実行すると、以下のような結果が出力されます。
こんにちは。ロボットを起動しました 切ってます 焼いてます