[Java] 内部クラス と 静的ネストクラス

わかりやすいJava_オブジェクト指向編を読んで勉強中。。

いろいろとややこしいネストクラスのメモ。

内部クラス複雑すぎワロタ

public class 複雑な内部クラス {
  public class Inner extends Base implements IBase {}
  private interface IBase {}
  private abstract class Base {
      private class InnerInner extends 複雑な内部クラス{};
  }
}

まぁ複雑さを回避するための内部クラスなので こんな訳のわからないことはするはずないけど…

内部クラスのインスタンス生成

package jp.fernweh;

public class Outer {

  public static void main(String[] args) {
    new Outer().test();
  }

  private void test() {
    new Inner();
    new PublicInner();
    new ProtectedInner();
    new PrivateInner();
  }

  class Inner {}
  public class PublicInner {}
  protected class ProtectedInner {}
  private class PrivateInner {}
}

class Other {
  public void invoke() {
    Main instance = new Main();
    instance.new Inner(); // 別パッケージからだとコンパイルエラー
    instance.new PublicInner();
    instance.new ProtectedInner(); // 別パッケージからだとコンパイルエラー
    // instance.new PrivateInner(); // コンパイルエラー  
  }
}

protedted の場合と、可視性の指定子をつかなかった場合の違いがわからないな…そもそもインナークラスを別パッケージのクラスが継承できる気がしないんだけど…まぁ仮にできたとしても有効な使用法思いつくほど頭良くないので別にいいか…

外部クラスのメンバは内部クラスから自由にアクセスできる

package jp.fernweh;

public class HogeTest {

  private String str;

  private String getStr() {
    return str;
  }

  class Inner {
    public void invoke() {
      // 内部クラスは外部クラスのメンバに自由にアクセスできる。
      str = getStr();
      HogeTest.this.str = HogeTest.this.getStr();
    }
  }
}

内部クラスのメンバに外部クラスから自由にアクセスできる。

package jp.fernweh;

public class HogeTest {

  public static void main(String[] args) {
    new HogeTest().invoke();
  }
  public void invoke() {
    Inner inner = new Inner();
    inner.str = inner.getStr();
  }

  class Inner {
    private String str;
    private String getStr() {
      return Inner.this.str;
    }
  }
}

静的ネストクラス

ネストクラスに static 指定子 をつけたものは静的ネストクラスと呼ばれる。 クラス内に定義したクラスで、内部クラスとは違って外部クラスのインスタンス無しに new できる。ただし、外部クラスの可視性の影響は受ける。 static フィールドみたいに最初からインスタンスを持つわけではないので注意。

package jp.fernweh;

public class HogeTest {
  public static void main(String[] args) {
    new Outer.Nested();
    new Outer.Nested.NestedNested(); // 可視性によりコンパイルエラー
    new Outer.Nested.NestedNested.NestedInterface() {}; // 可視性によりコンパイルエラー
  }
}

class Outer {
  public static class Nested {
    private static class NestedNested {
      public static interface NestedInterface{}
    }
  }
}
Share
関連記事