🦊

Java: インターフェース を 初歩から 振り返ってみた

に公開

プロローグ

こんにちは。もう冬ですね。
この記事は、私が本やネットで勉強して自分なりに言葉にしたものです。自分の備忘録みたいなものです。 なので内容に関して誤りもあるかもしれませんが、あしからずご了承くださいませ。

テーマ

今回、Javaのインターフェースについて学びなおしの一環として書いています。

前置き

以下より、淡白な文章となっています。それだけインターフェースは、初心者が自分なりに文章にし、見よう見真似で記載したところで、深いテーマであり、私自身理解が及んでいないことを痛感しております。

インターフェースとは

インターフェースは、変数の型やメソッドの返り値として使 えます。
これは、もちろん決まりではなく開発側の考えに基づくところにあると思います。

また クラスと違い実体化はできません。
インターフェースはオブジェクトにどんな操作が可能かを意識させます。
決められたオブジェクトを受け入れることができることを示していると考えます。
要は、一つの意思表明ができるものと考えていいとのこと。

変数定義について

インターフェースを用いた変数定義で、Listインターフェースを例に示します。

//① 変数の型がインターフェース
List<String> list = new ArrayList<>();
//list.trimToSize(); エラー
//② 変数の型がクラス
ArrayList<String> list = new ArrayList<>();
list.trimToSize();

上記コードだと、メソッドは変数の型で制約をうけるため、①のインターフェース型ではエラーとなります。保有しているオブジェクトの機能が限定されている状態となっています。

ただしこの考え方自体は、インターフェースからの視点では適切ではないとのことです。
①の変数だと、List型インターフェースを継承している他のクラスを参照できる、広範囲なクラスを参照できるとも言えるからです。 多態性が増したコードとなります。

もし仮にクラスを ArrayListクラス から LinkedListクラスに変更しても、変数定義以降のコードを
気にかける必要はそれほどなく、保守性の高い堅牢なコードとなりえます。

私たちが自作のインターフェースを作成する場合、
変化しにくい個所(メソッド)をインターフェースで宣言することで不変であることの意思を示す
このことを心がける必要があると、本によっては記載あります。

インターフェース内の変数とメソッドの修飾子について

インターフェース内の変数とメソッドは、開発側で記載しなくても暗黙で修飾子がつきます。
以下参照ください。

//へんてこな例ですいません
interface Game {
    //変数はすべて暗黙で "public static final" がつく。つまりすべて定数となる
    public static final String strTitle = "interface...";
    //defaultメソッドは暗黙で "public"がつく
    public default void targetAgeStatus(int nAge) {
    }
    //staticメソッドも同様暗黙で "public"がつく
    public static void setTitle(String title) {
    }
    //privateはそのまま
    private void electricityUsageRate() {
    }
    //抽象メソッドは暗黙で "public abstract"がつく
    public abstract void boot();
}

Java Silver資格試験でよく問われる箇所かと思います。

インターフェースと抽象クラスの使い分け

実装時、具像クラスは抽象クラス(基底クラス)を拡張継承し、堅牢にするため型定義として使用できるようインターフェースを実装させる、例として以下 ArrayListの宣言の一部を記載しています。

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

こちら 抽象クラスを基底クラスとし、型継承としてListインターフェースが実装されている。
また、以下のようにAbstractListクラスのメソッドをArrayList側でoverrideされている。

//AbstractListのaddメソッド
public void add(int index, E element) {
    throw new UnsupportedOperationException();
}
//ArrayListのaddメソッド
public void add(int index, E element) {
    rangeCheckForAdd(index);
    modCount++;
    final int s;
    Object[] elementData;
    if ((s = size) == (elementData = this.elementData).length)
        elementData = grow();
    System.arraycopy(elementData, index, elementData, index + 1, s - index);
    elementData[index] = element;
    size = s + 1;
}

エピローグ

ここまで読んで頂きありがとうございます。
数日前 私が10年愛用してきたPCが故障し意気消沈しておりました。Linuxの勉強をしていくうえで
ある程度高スペックなPCを探しています。 Mac miniでも購入して仮想環境作ろうか考えている今日この頃悩み中です。

Discussion