Javaでオブジェクト指向を勉強を初めた初心者にとって、
implementsって何のためにあるの?
と疑問に思ってしまう方も多いのではないでしょうか?
でも、使い方がわかると後々で柔軟に対応がとれるようになるので、けっこう便利なんです。
そこで、この記事では
- 【基礎】interfaceの使い方
- 【発展】interfaceとdefaultの使い方
- 【発展interfaceとstaticの使い方
- 【発展】interfaceとabstract(抽象クラス)との違い
などの基礎から応用的な内容についても解説していきます。
今回はinterfaceやimplementsについて、使い方をわかりやすく解説します!
この記事の目次
interfaceの使い方
interfaceでは、定数とメソッド名のみ定義できます。
定義する変数は「public static final」が付いているものとみなされ、定数として扱われます。
また、実装したクラスではメソッドの実装が必須となります。
interfaceの宣言と実装について
インターフェースの宣言は下記のように記述します。
インターフェースの宣言例:
interface インターフェース名 { メンバー変数の定義; メンバーメソッドの型の定義; }
インターフェースを実装する場合には「implements」句を使用し下記のように記述します。
インターフェースの実装例:
class クラス名 implements インターフェース名 { ・・・ }
メソッドを実装する方法
それではサンプルコードでメソッドを実装する方法についてみていきましょう。
//インターフェースの宣言 interface Calc1{ //メンバ変数(定数) public String STR = "足し算"; public int A = 3; public int B = 6; //メソッド(型のみ宣言) void method1(); void method2(String str); void method3(); } //インターフェースの実装 class Add implements Calc1{ // メソッドの実装 public void method1() { System.out.println(STR + "をします"); } public void method2(String str) { System.out.println(str + "をします"); } public void method3() { System.out.println("計算結果: " + (A + B)); } } //実行Mainクラス public class Main { public static void main(String[] args) { Add add = new Add(); add.method1(); //”足し算をします"の表示 add.method3(); //定数の足し算の結果表示 } }
実行結果:
足し算をします 計算結果: 9
このサンプルコードでは、まずCalc1インターフェースを宣言しています。
文字列型とint型の定数を定義し、3種類のメソッドの型だけを宣言しています。これをAddクラスで実装しています。
Addクラス内ではCalc1インターフェースで宣言したメソッドの処理内容を記述しています。
実行(Main)クラスではAddクラスをインスタンス化し、Addクラスで記述したメソッドの処理が実行されています。
処理内容を変える方法
それでは次に、処理を変える必要が出てきた場合をみていきましょう。
これまでは足し算の処理でしたが、掛け算に変えてみます。
サンプルコードをみていきましょう。
//インターフェースの宣言 interface Calc1{ //メンバ変数(定数) public String STR = "足し算"; public int A = 3; public int B = 6; //メソッド(型のみ宣言) void method1(); void method2(String str); void method3(); } //インターフェースの実装 class Add implements Calc1{ // メソッドの実装 public void method1() { System.out.println(STR + "をします"); } public void method2(String str) { System.out.println(str + "をします"); } public void method3() { System.out.println("計算結果: " + (A + B)); } } // 処理内容の変更用のクラス class Multiply implements Calc1{ // メソッドの実装 public void method1() { System.out.println(STR + "をします"); } public void method2(String str) { System.out.println(str + "をします"); } public void method3() { System.out.println("計算結果: " + (A * B)); // 掛け算に変更 } } //実行Mainクラス public class Main { public static void main(String[] args) { Multiply mul = new Multiply(); mul.method2("掛け算"); //”掛け算をします"の表示 mul.method3(); //定数の足し算の結果表示 } }
実行結果:
掛け算をします 計算結果: 18
このサンプルコードでは、計算処理内容の変更のためにMultiplyクラスを追加し、Mainクラスの記述の一部を変更しています。このようにクラスの追加と実行処理の記述の一部を変更することで処理内容を変更することができます。
ここで、注意があります。
足し算から掛け算に変更したので、表示する文字列を"掛け算をします"に変更しました。
その際に
mul.STR = “掛け算”;
と記述したくなりますが、これは出来ません。
Calc1インターフェースで
public String STR
と定義していても、「public static final」が付いているものとみなされ、定数として扱われるからです。
注意しましょう!
この例では、AddクラスとMainクラスの記述されている場所が近いので、このような書き方をすると確かに"なぜ?"となるかもしれません。
しかし、例えばCalc1インターフェースとAddクラスがMainクラスとは別のファイルに記述されている場合はどうでしょうか?処理を変更したい場合は、Addクラスを見つけ出して書き直す必要がありますよね。
でもinterfaceを使えば、MultiplyクラスのようにMainクラスと同じファイル内に処理の変更を記述することができます。
探して書き換える手間が省けるのがメリットなのです。
処理が複雑になり記述量が多くなると、多数のファイルに分けて記述するという機会が増えます。
そんな場合はinterfaceでメソッドの型だけ宣言しておいて処理は別で記述する方が、後々の変更などが予想される場合には便利になってくるのです。