0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Java】入れ子クラス

Posted at

#入れ子クラス(Nested Class)

  • 入れ子クラス(Nested Class)
    • staticメンバークラス
    • 内部クラス(Inner Class)
      • 非staticメンバークラス
      • 匿名クラス

##staticメンバークラス

  • 特定クラス(MyClass)にクラス(MyHelper)が依存、MyHelperはMyClassからしか呼ばれない
  • →1個の.javaファイルにまとめることを考える
  • トップレベルクラス:ネストしてないファイル直下のクラス
  • エンクロージングクラス:入れ子のクラスを内側に含んだクラス
    • 親クラスX:エンクロージングクラスかつトップレベルクラス
    • 子クラスY:ZのエンクロージングクラスでXの入れ子クラス
    • 孫クラスZ:Yの入れ子クラス
public class MyClass{...}
class MyHelper{...}
  • しかし、MyHelperはあくまでパッケージプライベートで、同じパッケージからは自由にアクセスできる
  • staticでMyClassのプライベートにすべき!
  • エンクロージングクラスのclassブロック配下で入れ子クラス定義すると
    • 入れ子クラスはエンクロージングクラス外からは見えない
    • 入れ子クラスの名前は**エンクロージングクラス.入れ子クラス(MyClass.MyHelper)**
      • エンクロージング内部ではメンバークラス名で呼び出し可能
      • import (package名).MyClass.MyHelper;
        でエンクロージング外からも
        var h = new MyHelper();可能
//classブロック配下でMyHelper定義
public class MyClass {
  //staticメンバークラスの定義
  //メンバーはMyClass外からは見えない
  private static class MyHelper {
    public void show() {
      System.out.println("Nested class is running!");
    }
  }
  public void run() {
    //エンクロージング内部ではMyHelper呼び出し可能
    var helper = new MyHelper();
    helper.show();
  }
}
public class NestBasic {
  public static void main(String[] args) {
    var c = new MyClass();
    c.run();
    //MyHelpeはMyClass外からは見えない
    // var h = new MyClass.MyHelper(); //エラー!
  }
}

##非staticメンバークラス(=内部クラス)

  • static修飾子なし
  • 内部クラス:エンクロージングオブジェクトに所属
  • staticメンバークラス:エンクロージングクラスに所属
  • 内部クラスの特徴
    • 内部クラスをインスタンス化するにはエンクロージングオブジェクト必要
    • 内部クラスからはthis変数経由でエンクロージングクラスメンバーにアクセス
  • エンクロージングクラスのインスタンスフィールド参照用途に使用
  • 個々のインスタンスがエンクロージングオブジェクトへの参照を持つのでメモリを消費する
class MyClass {
  private String str1 = "エンクロージング・インスタンス";
  private static String str2 = "エンクロージング・クラス";

  private class MyHelper {
    private String str1 = "ネスト・インスタンス";
    private static final String str2 = "ネスト・クラス";

    public void show() {
      //内部クラスはエンクロージングオブジェクトへの参照を持つ
      //MyClass.thisでアクセス可
      System.out.println(MyClass.this.str1); //エンクロージング・インスタンス
      System.out.println(MyClass.str2); //エンクロージング・クラス
    }
  }

  public void run() {
    //内部クラスのインスタンスはエンクロージングクラスのインスタンスメソッドで生成
    var helper = new MyHelper();
    helper.show();
    //エンクロージングオブジェクトから内部クラスにアクセス
    System.out.println(helper.str1); //ネスト・インスタンス
    System.out.println(MyHelper.str2); //ネスト・クラス
  }
}

public class NestedAccess {
  public static void main(String[] args) {
    var c = new MyClass();
    c.run();
  }
}

##非staticメンバークラス(内部クラス)の実例

  • private内部クラスを宣言したらエンクロージング外からは見えない
  • 見えなくなるのは型名のみ、インスタンスの参照は制限なし
java.util.AbstractList.java
package java.util;
import java.util.function.Consumer;
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
//...中略

    /*Iterators
    Itrクラスの内部的な実装を見せる必要はない
    外部からは実装元であるIterators型が見えたらいい
    iteratorメソッドの戻り値はIterator型
    */
    public Iterator<E> iterator() {
        return new Itr();
    }
//...中略

    /*内部クラス
    リスト内のprivateフィイールドにアクセス、配下要素を順にアクセスするイテレータを実装
    イテレータはIterator実装クラスとして別に定義する
    */
    private class Itr implements Iterator<E> {
//...中略
    }
//...中略
}

##匿名クラス(無名クラス)

  • 特定の処理をまとめて表すための器として使う
  • ex:イベントリスナー
    • 特定の文脈(ユーザーの動作など)に強く関連するので他では再利用しない
  • new 基底クラス(引数,...){クラスの本体}
    • new View.OnClickListener(){
    • 匿名クラスには名前がないのでnew演算子に基底クラス/インターフェースの名前を指定
    • 用意したリスナーのインスタンスにはそのままメソッドに渡せる
  • 注意;
    • コンストラクタを持てない(初期化はOK)
    • 継承不可(暗黙的にfinal)
    • 抽象クラス宣言不可
//イベントリスナー登録
btn.setOnClickListener(
  //匿名クラス(イベントリスナー)定義
  new View.OnClickListener(){
    //btnクリックでtxtに現在時刻を表示
    @Override
    public void onClick(View view){
      TextView txt = findViewById(R.id.txtResult);
      txt.setText(LocalDateTime.now().toString());
    }
  }
);

##ローカルクラス

  • メソッド、コンストラクタなどブロック配下で定義されたクラス
  • クラスが特定のメソッド、コンストラクタで利用されるときに使う
  • 匿名クラスで代用OK
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?