インターフェイス - interface - 萌えJava超入門
クラスの継承

インターフェイス

インターフェイスは、クラスの仲間

interface

implements

目次

1. インターフェイスとは


インターフェイスとは
  インターフェース(interface)とは、
  すべてのインスタンスメソッドが抽象メソッドであることを
  約束されたのクラスです。

インターフェースの宣言
  //インターフェース名.java
  interface インターフェース名{
        void method01(); //抽象メソッド
  }

↓↓↓ 実装 ↓↓↓

インターフェースの実装
  //クラス名.java
  public class クラス名 implements インターフェース名 {

  @Override
  public void method01(){
      //処理内容
  }


萌えJava超入門 萌えJava超入門 萌えJava超入門
それじゃ。
少しずつ解説するぞ。


2. インターフェースの宣言


interface

interfaceキーワードを使って宣言します。

萌えJava超入門 萌えJava超入門
あっ!
「class」じゃない!
interfaceキーワード
  //インターフェース名.java
  interface インターフェース名{
        //内容
  }

インターフェースは、
「すべてのインスタンスメソッドが抽象メソッドである抽象クラス」とは違います

そもそも、abstract class ではなく、
interface で宣言します。

でも、ソースファイルを保存するときの拡張子は普通に「.java」です。

萌えJava超入門 萌えJava超入門
なぜ悪役?
萌えJava超入門
ふっふっふ。
驚いたか?


3. インターフェースの書き方


インターフェースに定義できることはとても限られています。

萌えJava超入門
初めのうちは
「抽象メソッドのみ」
くらいに考えていいと思う。
インターフェースの特徴
  1. インターフェースのメンバは、すべて暗黙的に public が付与されます。
  2. インスタンスメソッドは、すべて暗黙的に public abstract が付与されます。
      (default による例外があります。)
  3. 変数には、すべて暗黙的に public static final が付与されます。
      (インスタンス変数は持てません。)
  4. クラスメソッド(static)は処理を実装できます。

萌えJava超入門 萌えJava超入門
「暗黙的に」ってことは
書かなくていいってこと?
萌えJava超入門
Yes.
暗黙的に付与される修飾子まとめ
 メンバ 暗黙的に付与される修飾子 
 変数 public static final
 クラスメソッド(static) public
 インスタンスメソッド public abstract
インスタンス変数は持てません。

萌えJava超入門
すべてのインスタンスメソッドが
抽象メソッドなので、
abstract も書かなくていいぞ。
インターフェースの例
  //インターフェース名.java
  interface インターフェース名{
      void method01(); //暗黙的に public abstract が付与されます
      void method02(); //暗黙的に public abstract が付与されます
  }


重要
すべてのインスタンスメソッドが抽象メソッドです。

重要
インスタンス変数を持てません。



4. インターフェースの実装


implements

インターフェースの実装には「implements」 を使用します。

萌えJava超入門
ここでちょっとポイント。
インターフェースの場合
「継承」ではなく「実装」という。
萌えJava超入門 萌えJava超入門
なんでじゃ?
萌えJava超入門
インターフェースの
抽象メソッドを
実装する行為そのもの
だからだろう。
インターフェースの例
  //インターフェース名.java
  interface インターフェース名{
        void method01();
        void method02();
  }

↓↓↓ 実装 ↓↓↓

インターフェースの実装
  //クラス名.java
  public class クラス名 implements インターフェース名 {

  @Override
  public void method01(){
      //処理内容
  }

  @Override
  public void method02(){
      //処理内容
  }



5. 複数のインターフェースを実装する


implements インターフェース1, インターフェース2 {

重要
インターフェースは多重実装が可能です。

重要
複数のインターフェースを実装する場合は、「,」(カンマ)で区切ります。

萌えJava超入門
インターフェイスは
「クラスの多重継承問題」に対する
一つの答えだ。
萌えJava超入門 萌えJava超入門
インスタンス変数を排除した上で
メソッドの実装を継承後に行うことで、
安全な多重継承を実現したと?
萌えJava超入門
そうゆう感じだ。
複数のインターフェースを実装する場合は、「,」(カンマ)で区切ります。
インターフェース1
  //インターフェース名1.java
  public interface インターフェース名1{
        void method01();
        void method02();
  }

インターフェース2
  //インターフェース名2.java
  public interface インターフェース名2{
        void method03();
        void method04();
  }

萌えJava超入門
紙面の都合で改行しているが、
普通にカンマ区切りで大丈夫だ。
複数のインターフェースを実装
  //クラス名.java
  public class クラス名
          implements インターフェース名1 , インターフェース名2 {

  @Override
  public void method01(){
      //処理内容
  }
  @Override
  public void method02(){
      //処理内容
  }
  @Override
  public void method03(){
      //処理内容
  }
  @Override
  public void method04(){
      //処理内容
  }




6. サンプル1 インターフェースの実装


ISpeak がインターフェースです。
「class」ではなく、「interface」で宣言します。 インスタンスメソッドはすべて暗黙的に public abstract が付与されますので、 記述しなくても OKです。

//ISpeak.java
public interface ISpeak {
      void printName();
      void sayWish();
}

ISpeakを実装した2つのクラス(Dog_91、Cat_91)を作っています。

//Dog_91.java
public class Dog_91 implements ISpeak {

      protected String name1;
      public Dog_91(String name){
          this.name1 = name;
      }

      @Override
      public void printName(){
          System.out.println(name1 + "だワン!");
      }

      @Override
      public void sayWish(){
          System.out.println(name1 + "は棒には当たらないワン!");
      }

}

//Cat_91.java
public class Cat_91 implements ISpeak {

      protected String name2;
      public Cat_91(String name){
          this.name2 = name;
      }

      @Override
      public void printName(){
          System.out.println(name2 + "なのにゃ!");
      }

      @Override
      public void sayWish(){
          System.out.println(name2 + "は小判が欲しいのにゃ!");
      }

}

萌えJava超入門 萌えJava超入門
ちょっと待って!
なんで Dog_91クラスは、name1 で、
Cat_91クラスは、name2 なの?
萌えJava超入門
抽象クラスと
インターフェースとの違いを
強調したくて。
インターフェースはインスタンス変数を持てません。
このため、同じような使い方をする変数であっても、
それぞれのサブクラスで個別に宣言する必要があります。
「継承された変数」ではないことにご注目ください。

萌えJava超入門
配列がインターフェースの
ISpeak型だぞ。
//Driver_91.java

public class Driver_91{

    public static void main(String[] args){
        ISpeak[] animalArray = new ISpeak[6];
        animalArray[0] = new Dog_91("ヨーゼフ");
        animalArray[1] = new Dog_91("パトラッシュ");
        animalArray[2] = new Dog_91("白いお父さん");
        animalArray[3] = new Cat_91("ニャース");
        animalArray[4] = new Cat_91("ドラえもん");
        animalArray[5] = new Cat_91("ニャンパス");

        for(int i=0; i<animalArray.length; i++){
            animalArray[i].printName();
            animalArray[i].sayWish();
        }
    }
}

萌えJava超入門 萌えJava超入門
インターフェースの
変数も作れるのね。
萌えJava超入門
ISpeak を実装した
クラスだけが
代入できる。
ISpeak.java
Dog_91.java
Cat_91.java
Driver_91.java
を wsフォルダに保存して実行します。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_91.java
ws>java Driver_91
ヨーゼフだワン!
ヨーゼフは棒には当たらないワン!
パトラッシュだワン!
パトラッシュは棒には当たらないワン!
白いお父さんだワン!
白いお父さんは棒には当たらないワン!
ニャースなのにゃ!
ニャースは小判が欲しいのにゃ!
ドラえもんなのにゃ!
ドラえもんは小判が欲しいのにゃ!
ニャンパスなのにゃ!
ニャンパスは小判が欲しいのにゃ!


Dog_91も、Cat_91も、ISpeakを実装しているので、
ISpeak型の変数に代入できました。
ISpeakの、printNameメソッドと、sayWishメソッドを実行できます。



7. サンプル2 extendsとの併用

implements は、extends と併用できます。
Animal_09クラスでは、インスタンス変数「name」と、nameを初期化するコンストラクタを宣言しています。
インスタンス変数周りはクラスで宣言して、インスタンスメソッドの定義は、インターフェースで行う作戦です。

萌えJava超入門
共通のインスタンス変数を持つ
サブクラスを作る場合は、
クラスの継承を併用するのもありだ。
//Animal_09.java

public  class Animal_09 {
      protected String name; //ここで変数を宣言
      public Animal_09(String name){
          this.name = name;
      }
}

Animal_09ISpeak を実装した2つのクラス(Dog_92、Cat_92)を 作っています。
変数「name」を Animal_09から継承しています。

//Dog_92.java
public class Dog_92 extends Animal_09 implements ISpeak {
      public Dog_92(String name){
          super(name);
      }

      @Override
      public void printName(){
          System.out.println(name + "だワン!");
      }

      @Override
      public void sayWish(){
          System.out.println(name + "は棒には当たらないワン!");
      }

}

萌えJava超入門
extends Animal_09
implements ISpeak
の間は半角空白文字ね。
//Cat_92.java
public class Cat_92 extends Animal_09 implements ISpeak {
      public Cat_92(String name){
          super(name);
      }

      @Override
      public void printName(){
          System.out.println(name + "なのにゃ!");
      }

      @Override
      public void sayWish(){
          System.out.println(name + "は小判が欲しいのにゃ!");
      }

}

//Driver_92.java

public class Driver_92{

    public static void main(String[] args){
        ISpeak[] animalArray = new ISpeak[6];
        animalArray[0] = new Dog_92("ヨーゼフ");
        animalArray[1] = new Dog_92("パトラッシュ");
        animalArray[2] = new Dog_92("白いお父さん");
        animalArray[3] = new Cat_92("ニャース");
        animalArray[4] = new Cat_92("ドラえもん");
        animalArray[5] = new Cat_92("ニャンパス");

        for(int i=0; i<animalArray.length; i++){
            animalArray[i].printName();
            animalArray[i].sayWish();
        }
    }
}

ISpeak.java
Animal_09.java
Dog_92.java
Cat_92.java
Driver_92.java
を wsフォルダに保存して実行します。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_92.java
ws>java Driver_92
ヨーゼフだワン!
ヨーゼフは棒には当たらないワン!
パトラッシュだワン!
パトラッシュは棒には当たらないワン!
白いお父さんだワン!
白いお父さんは棒には当たらないワン!
ニャースなのにゃ!
ニャースは小判が欲しいのにゃ!
ドラえもんなのにゃ!
ドラえもんは小判が欲しいのにゃ!
ニャンパスなのにゃ!
ニャンパスは小判が欲しいのにゃ!


萌えJava超入門 萌えJava超入門
ファイル数が
増えましたね~。
萌えJava超入門
そうだな。
このように機能別にファイルを分けて
継承や実装を利用することで
拡張性やメンテナンス性を向上している。
実感できるのはもうちょっと先かなぁ。


8. サンプル3 インターフェースのクラスメソッド


おまけです。
インターフェースのクラスメソッド(staticメソッド)は、インターフェースで実装可能です。
クラスと同様に使用できます。

//ISpeakSt.java

public interface ISpeakSt {

      String group = "生き物です。"; //public static final が付与
      static void printGroup(){ //public が付与
          System.out.println(group);
      }
      void printName();
      void sayWish();
}

//Driver_93.java
public class Driver_93{
    public static void main(String[] args){
        ISpeakSt.printGroup(); //クラスメソッドの実行
    }
}

ISpeakSt.java
Driver_93.java
を wsフォルダに保存して実行します。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Driver_93.java
ws>java Driver_93
生き物です。


萌えJava超入門
クラスメソッドだから
インスタンス化なしで
そのまま実行できる。



お疲れ様でした。




© 2019 awasekagami