2010年9月12日 星期日

Inner Class 和 Nested Class

  1. What is nested class? - If all the methods of a inner class is static then it is a nested class.
  2. What is inner class? - If the methods of the inner class can only be accessed via the instance of the inner class, then it is called inner class.

Inner Classes 與 Nested Classes
[class-modifiers] class OuterClassName {
  ‥‥
  [inner-class-modifiers] class InnerClassName {
    ‥‥
  }
  [nested-class-modifiers] static class StaticClassName {
    ‥‥
  }
  ‥‥
}


Inner Class
Java 將 Inner Class 分為下列 3 類
‧ 一般的 Inner Class
指的是將 class 宣告在 class 內
[語法]
[class-modifiers] class EnclosingClass {
  [inner-class-modifiers] class InnerClass {
    // Write Codes Here
  }
}
 inner-class-modifiers 可以是 public、protected、private、final、strictfp、abstract、static(會變成static nested class)

1. 若在 enclosing class 之外建立 inner class 的 instance,必須先建立 enclosing class 的 instance。
 [範例]
 EnclosingClass.InnerClass obj = new EnclosingClass( ).new InnerClass( );
 或是
 EnclosingClass objX = new EnclosingClass( );
 EnclosingClass.InnerClass objY = objX.new InnerClass( );

2. 所有的 inner class 會隱性參考(reference) 其 enclosing class,其型式為 "EnclosingClass.this"
 [範例]
 public class MyEnclosingClass {
   private String someMember = "Some Member";
   private class MyInnerClass {
     private String someMember = "Inner Member";
     public void doIt( ) {
       System.out.println(someMember);  // 印出 Inner Member
       System.out.println( MyEnclosingClass.this.someMember );  // 印出 Some Member
     }
   }

   public static void main(String[ ] args) {
     new MyEnclosingClass( ).new MyInnerClass( ).doIt( );
   }
 }

3. non-static inner class 可存取包含該 inner class 的所有的 members。
4. inner class 內不能宣告 static members,inner class 內所有 members 必須是 instance members,但是 inner classes 可
 存取 enclosing class 的 static members。
 唯一的例外是,inner classes 內可宣告 static 和 final 的 fields(compile-time constant)。

[範例]
class HasStatic {
static int j = 100;
}
class Outer {
class Inner extends HasStatic {
static final int x = 3; // ok - compile-time constant
static int y = 4; // compile-time error, an inner class
}
static class NestedButNotInner {
static int z = 5; // ok, not an inner class
}
interface NeverInner { } // interfaces are never inner
}


‧ Method local Inner Class
1. local class 為定義在 method 內的 class,其 scope 在該 method 內
2. 當 inner class 定義在 method 內,則該 class 只可以存取 enclosing class 宣告為 final 的 variables(或稱為 automatic 或 local variables)

[範例]
public class MyInnerClass {
static String msg = "Hello";

public static void main(String[ ] av) {
class Inner {
public void doSomeWork( ) { // print member of enclosing class
System.out.println(msg);
}
}
Inner p = new Inner( );
p.doSomeWork( );
}
}


‧ Anonymous Inner Class
1. anonymous nested class 必須實作某個 interface 或是繼承某個 class,但是不使用 implements 或 extends 關鍵字做宣告。
2. anonymous class 內不能宣告 constructor,可宣告 instance initializer 做初值設定
[註] anonymous class 的類別名稱可用 this.getClass( ).getName( ) 觀察

[範例]
return new SomeClass( ) {  /*body of the anonymous class goes here*/  };

[範例]
someMethod(new SomeClass( ) {  /*body of the anonymous class goes here*/  } );

Nested Class
Nested Classes 也是 inner class 的一種型式,但是 Java 將宣告為 static 的 inner class 稱為 Nested Class
‧ Static Nested Classes
1. nested classes 即為所謂的 static inner classes
 nested classes 有點像似 top-level classes,enclosing class 提供這種類型的 class 一個 package-like 的架構,nested classes 可
 存取 enclosing class 所有的 members。但是 nested class 比 inner class 有更多的限制。
2. static nested class 可以合用修飾字 abstract。
 [註] 注意,一般而言,在 class 內你不能宣告 static methods 為 abstract。
3. 可直接建立 nested class 的 instance,不需先建立 enclosing class 的 instance。
 EnclosingClass.NestedClass obj = new EnclosingClass.NestedClass( );
4. nested class 只能存取 enclosing class 的 static members(private 權限的 members 亦可)
 
[範例]
public class MyEnclosingClass {
  private static String staticMember = "Static Member";
  private String someMember = "Some Member";
  static class MyNestedClass {
    public void doIt( ) {
      System.out.println(staticMember);
    }
  }

  public static void main(String[ ] args) {
    new MyNestedClass( ).doIt( );
    // new MyInnerClass( ); // ERROR
  }

  class MyInnerClass {
    // static String InnerStaticMember = "Inner Static Member"; // Error:inner classes cannot have static declarations
    public void doIt( ) {
      System.out.println(staticMember + ", " +myStaticFinalConstant);
    }
    static final int myStaticFinalConstant = 0; // OK
  }
}


※ inner interface 與 inner class 混用
1. interface 內的 inner interface 預設為 public static,class 內的 inner interface 預設為 static,存取權限可以為 private/protected/public/default
2. class 的 inner class 內不能再有 inner interface,否則會出現編譯錯誤:inner classes cannot have static declarations
3. Interface 的 Inner Class 內可以有 Inner Interface
4. Interface 內可以有 Inner class
5. Inner Interface 可以繼承 Outer Intreface
6. Inner Class 可以繼承 Outer Class 或 implments Outer Interface

[範例]
public class X {
  class Y {
    private void f( ) { }
  }
  class Z extends Y {
    { // initializer
      f( );    // 編譯錯誤
      this.f( );  // 編譯錯誤
      ((Y)this).f( ); // 可過編譯
      super.f( ); // 可過編譯
    } //end initializer
  }
} // end class X

2 則留言:

  1. 介紹的好詳細! 謝謝樓主!
    另外有問題想請教:
    Nested Class的介紹中,第一點與第四點是否有衝突呢? 或是我會錯意了?
    1.nested classes 可
     存取 enclosing class 所有的 members。但是 nested class 比 inner class 有更多的限制。
    4.nested class 只能存取 enclosing class 的 static members(private 權限的 members 亦可)

    回覆刪除