2008年4月14日 星期一

inner.java, a sample code for 6 kinds of java classes inside classes/methods

/*

  Inner.java

    Demo for a variety of inner classes which include

1. static nested classes: 類別內具名靜態類別 InClassStaticClass
 no associated outer class instance.

2. inner nested classes: 類別內具名非靜態類別 InClassInstanceClass
 with an associated outer class instance.

3. anonymous classes: 方法內匿名類別 adapted from InMethodUnnamedClass
 unnamed inner class defined in the middle of a method.

4. local classes: 方法內具名類別 InMethodStaticClass, InMethodInstanceClass
 named inner class defined in the middle of a method.

實際展示6種內部類別(inner class)寫法:
 1.類別內具名靜態類別,InClassStaticClass
 2.類別內具名非靜態類別,InClassInstanceClass
 3.類別方法內具名靜態類別,InMethodStaticClass
 4.物件方法內具名非靜態類別,InMethodInstanceClass
 5.類別方法內匿名靜態類別,adapted from InMethodUnnamedClass
 6.物件方法內匿名非靜態類別,adapted from InMethodUnnamedClass

Note:
 1.StaticClass can directly instantiate without an instance.
   An inner InstanceClass can have static and instance members,
   but can only access outer class static members.
   Members include attributes and methods.
   Most classes are named StaticClass.
 2.InstanceClass must instantiate from an instance.
   An inner InstanceClass can only have instance members,
   but can access outer class static and instance members.
 3.Methods provide a non-static context and
   do not allow static declarations inside.
   All intra method inner classes can add
   new instance but not static members.
 4.Unnamed inner classes are adapted inline from known classes,
   and must be in a method, not in a class.
   They can add new instance but not static members and
   access old public but not private members of known classes.

Ref:
  http://www.blogjava.net/blackbat/archive/2006/10/04/73352.html

 執行方法及結果

> javac Inner.java
> java Inner
我是<外部類別OuterClass>物件,擁有
    類別屬性outerStaticAttribute
    物件屬性outerInstanceAttribute
    類別方法outerStaticMethod
    物件方法outerInstanceMethod

1.使用類別內具名靜態類別...
我是<類別內具名靜態類別InClassStaticClass>物件,擁有
    類別屬性innerStaticAttribute
    物件屬性innerInstanceAttribute
    類別方法innerStaticMethod
    物件方法innerInstanceMethod
 從類別方法innerStaticMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 內部類別之類別屬性innerStaticAttribute
  呼叫 外部類別之類別方法outerStaticMethod
 從物件方法innerInstanceMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 內部類別之類別屬性innerStaticAttribute
  存取 內部類別之物件屬性innerInstanceAttribute
  呼叫 外部類別之類別方法outerStaticMethod

2.使用類別內具名非靜態類別...
我是<類別內具名非靜態類別InClassInstanceClass>物件,擁有
    x類別屬性
    物件屬性innerInstanceAttribute
    x類別方法
    物件方法innerInstanceMethod
 從物件方法innerInstanceMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 外部類別之物件屬性outerInstanceAttribute
  存取 內部類別之物件屬性innerInstanceAttribute
  呼叫 外部類別之類別方法outerStaticMethod
  呼叫 外部類別之物件方法outerInstanceMethod

3.使用類別方法內具名靜態類別...
我是<方法內具名靜態類別InMethodStaticClass>物件,擁有
    x類別屬性
    物件屬性innerInstanceAttribute
    x類別方法
    物件方法innerInstanceMethod
 從物件方法innerInstanceMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 內部類別之物件屬性innerInstanceAttribute
  呼叫 外部類別之類別方法outerStaticMethod

4.使用物件方法內具名非靜態類別...
我是<方法內具名非靜態類別InMethodInstanceClass>物件,擁有
    x類別屬性
    物件屬性innerInstanceAttribute
    x類別方法
    物件方法innerInstanceMethod
 從物件方法innerInstanceMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 外部類別之物件屬性outerInstanceAttribute
  存取 內部類別之物件屬性innerInstanceAttribute
  呼叫 外部類別之類別方法outerStaticMethod
  呼叫 外部類別之物件方法outerInstanceMethod

5.使用類別方法內匿名靜態類別...
我是<方法內匿名靜態類別 adapted from InMethodUnnamedClass>物件,擁有
    類別屬性innerStaticAttribute.2
    物件屬性innerInstanceAttribute,2,3
    類別方法innerStaticMethod
    物件方法innerInstanceMethod
 從類別方法innerStaticMethod,我可以:
  存取 私密 內部類別之類別屬性innerStaticAttribute
  存取 公開 內部類別之類別屬性innerStaticAttribute2
 從 覆寫的 物件方法innerInstanceMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 舊有公開 內部類別之類別屬性innerStaticAttribute2
  存取 舊有公開 內部類別之物件屬性innerInstanceAttribute2
  存取 添加私密 內部類別之物件屬性innerInstanceAttribute3
  呼叫 外部類別之類別方法outerStaticMethod

6.使用物件方法內匿名非靜態類別...
我是<方法內匿名非靜態類別 adapted from InMethodUnnamedClass>物件,擁有
    類別屬性innerStaticAttribute,2
    物件屬性innerInstanceAttribute,2,3
    類別方法innerStaticMethod
    物件方法innerInstanceMethod
 從類別方法innerStaticMethod,我可以:
  存取 私密 內部類別之類別屬性innerStaticAttribute
  存取 公開 內部類別之類別屬性innerStaticAttribute2
 從 覆寫的 物件方法innerInstanceMethod,我可以:
  存取 外部類別之類別屬性outerStaticAttribute
  存取 外部類別之物件屬性outerInstanceAttribute
  存取 舊有公開 內部類別之類別屬性innerStaticAttribute2
  存取 舊有公開 內部類別之物件屬性innerInstanceAttribute2
  存取 添加私密 內部類別之物件屬性innerInstanceAttribute3
  呼叫 外部類別之類別方法outerStaticMethod
  呼叫 外部類別之物件方法outerInstanceMethod
*/
class OuterClass {
  private static String outerStaticAttribute = "外部類別之類別屬性outerStaticAttribute";
  private String outerInstanceAttribute = "外部類別之物件屬性outerInstanceAttribute";

  public OuterClass() {
    System.out.println(this);
  }

  public String toString() {
    String text = "";

    text = text + "我是<外部類別OuterClass>物件,擁有\n";
    text = text + "\t類別屬性outerStaticAttribute\n";
    text = text + "\t物件屬性outerInstanceAttribute\n";
    text = text + "\t類別方法outerStaticMethod\n";
    text = text + "\t物件方法outerInstanceMethod";

    return text;
  }

  // 外部類別靜態方法
  public static void outerStaticMethod() {
    System.out.println("  呼叫 外部類別之類別方法outerStaticMethod");
  }

  public static void outerStaticMethod2() {
    class InMethodStaticClass {
      //private static String innerStaticAttribute = "內部類別之類別屬性innerStaticAttribute";
      //  inner classes cannot have static declarations
      private String innerInstanceAttribute = "內部類別之物件屬性innerInstanceAttribute";

      public InMethodStaticClass() {
        System.out.println("我是<方法內具名靜態類別InMethodStaticClass>物件,擁有");
        System.out.println("\tx類別屬性");
        System.out.println("\t物件屬性innerInstanceAttribute");
        System.out.println("\tx類別方法");
        System.out.println("\t物件方法innerInstanceMethod");
      }

      public String toString() {
        return "我是<方法內具名靜態類別>物件";
      }

      //public static void innerStaticMethod()
      //  inner classes cannot have static declarations
      /*
      {
        System.out.println( " 從類別方法innerStaticMethod,我可以:");
        System.out.println( "  存取 " + outerStaticAttribute);
        //System.out.println( "  存取 " + outerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        System.out.println( "  存取 " + innerStaticAttribute);
        //System.out.println( "  存取 " + innerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        outerStaticMethod();
        //outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
      */

      public void innerInstanceMethod() {
        System.out.println(" 從物件方法innerInstanceMethod,我可以:");
        System.out.println("  存取 " + outerStaticAttribute);
        //System.out.println( "  存取 " + outerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        //System.out.println( "  存取 " + innerStaticAttribute);
        //  non-static variable cannot be referenced from a static context
        System.out.println("  存取 " + innerInstanceAttribute);
        outerStaticMethod();
        //outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
    }

    InMethodStaticClass imsc = new InMethodStaticClass();
    //imnic.innerStaticMethod();
    imsc.innerInstanceMethod();
  }

  public static void outerStaticMethod3() {
    InMethodUnnamedClass imuc = new InMethodUnnamedClass() {
      //private static String innerStaticAttribute3 = "內部類別之類別屬性innerStaticAttribute";
      //  inner classes cannot have static declarations
      private String innerInstanceAttribute3 = "內部類別之物件屬性innerInstanceAttribute3";

      public String toString() {
        String text = "";

        text = text + "我是<方法內匿名靜態類別 adapted from InMethodUnnamedClass>物件,擁有\n";
        text = text + "\t類別屬性innerStaticAttribute.2\n";
        text = text + "\t物件屬性innerInstanceAttribute,2,3\n";
        text = text + "\t類別方法innerStaticMethod\n";
        text = text + "\t物件方法innerInstanceMethod";

        return text;
      }

      //cannot overwrite constructor
      //  invalid method declaration; return type required
      //public InMethodUnnamedClass()
      /*{
        System.out.println( "我是<方法內匿名非靜態類別>物件,擁有" );
        System.out.println( "\tx類別屬性" );
        System.out.println( "\t物件屬性innerInstanceAttribute" );
        System.out.println( "\tx類別方法" );
        System.out.println( "\t物件方法innerInstanceMethod" );
      }*/

      //public static void innerStaticMethod()
      //  inner classes cannot have static declarations
      /*
      {
        System.out.println( " 從類別方法innerStaticMethod,我可以:");
        System.out.println( "  存取 " + outerStaticAttribute);
        //System.out.println( "  存取 " + outerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        System.out.println( "  存取 " + innerStaticAttribute);
        //System.out.println( "  存取 " + innerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        outerStaticMethod();
        //outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
      */

      //  overwriting method must exist in prototype class
      public void innerInstanceMethod() {
        System.out.println(" 從 覆寫的 物件方法innerInstanceMethod,我可以:");
        System.out.println("  存取 " + outerStaticAttribute);
        //System.out.println( "  存取 " + outerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        //System.out.println( "  存取 舊有私密 " + innerStaticAttribute);
        //  innerStaticAttribute has private access in InMethodUnnamedClass
        System.out.println("  存取 舊有公開 " + innerStaticAttribute2);
        //System.out.println( "  存取 添加私密 " + innerStaticAttribute3);
        //System.out.println( "  存取 " + innerInstanceAttribute);
        //  innerInstanceAttribute has private access in InMethodUnnamedClass
        System.out.println("  存取 舊有公開 " + innerInstanceAttribute2);
        System.out.println("  存取 添加私密 " + innerInstanceAttribute3);
        outerStaticMethod();
        //outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
    };

    imuc.innerStaticMethod();
    imuc.innerInstanceMethod();
  }

  // 外部類別物件方法
  public void outerInstanceMethod() {
    System.out.println("  呼叫 外部類別之物件方法outerInstanceMethod");
  }

  public void outerInstanceMethod2() {
    class InMethodInstanceClass {
      //private static String innerStaticAttribute = "內部類別之類別屬性innerStaticAttribute";
      //  inner classes cannot have static declarations
      private String innerInstanceAttribute = "內部類別之物件屬性innerInstanceAttribute";

      public InMethodInstanceClass() {
        System.out.println(this.toString());
      }

      public String toString() {
        String text = "";

        text = text + "我是<方法內具名非靜態類別InMethodInstanceClass>物件,擁有\n";
        text = text + "\tx類別屬性\n";
        text = text + "\t物件屬性innerInstanceAttribute\n";
        text = text + "\tx類別方法\n";
        text = text + "\t物件方法innerInstanceMethod";

        return text;
      }

      //public static void innerStaticMethod()
      //  inner classes cannot have static declarations
      /*
      {
        System.out.println( " 從類別方法innerStaticMethod,我可以:");
        System.out.println( "  存取 " + outerStaticAttribute);
        //System.out.println( "  存取 " + outerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        System.out.println( "  存取 " + innerStaticAttribute);
        //System.out.println( "  存取 " + innerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        outerStaticMethod();
        outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
      */

      public void innerInstanceMethod() {
        System.out.println(" 從物件方法innerInstanceMethod,我可以:");
        System.out.println("  存取 " + outerStaticAttribute);
        System.out.println("  存取 " + outerInstanceAttribute);
        //System.out.println( "  存取 " + innerStaticAttribute);
        //  non-static variable cannot be referenced from a static context
        System.out.println("  存取 " + innerInstanceAttribute);
        outerStaticMethod();
        outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
    }

    InMethodInstanceClass imic = new InMethodInstanceClass();
    //imic.innerStaticMethod();
    imic.innerInstanceMethod();
  }

  public void outerInstanceMethod3() {
    InMethodUnnamedClass imuc = new InMethodUnnamedClass() {
      //private static String innerStaticAttribute3 = "內部類別之類別屬性innerStaticAttribute";
      //  inner classes cannot have static declarations
      private String innerInstanceAttribute3 = "內部類別之物件屬性innerInstanceAttribute3";

      public String toString() {
        String text = "";

        text = text + "我是<方法內匿名非靜態類別 adapted from InMethodUnnamedClass>物件,擁有\n";
        text = text + "\t類別屬性innerStaticAttribute,2\n";
        text = text + "\t物件屬性innerInstanceAttribute,2,3\n";
        text = text + "\t類別方法innerStaticMethod\n";
        text = text + "\t物件方法innerInstanceMethod";

        return text;
      }

      //cannot overwrite constructor
      //  invalid method declaration; return type required
      //public InMethodUnnamedClass()
      /*{
        System.out.println( "我是<方法內匿名非靜態類別>物件,擁有" );
        System.out.println( "\tx類別屬性" );
        System.out.println( "\t物件屬性innerInstanceAttribute" );
        System.out.println( "\tx類別方法" );
        System.out.println( "\t物件方法innerInstanceMethod" );
      }*/

      //public static void innerStaticMethod()
      //  inner classes cannot have static declarations
      /*
      {
        System.out.println( " 從類別方法innerStaticMethod,我可以:");
        System.out.println( "  存取 " + outerStaticAttribute);
        //System.out.println( "  存取 " + outerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        System.out.println( "  存取 " + innerStaticAttribute);
        //System.out.println( "  存取 " + innerInstanceAttribute);
        //  non-static variable cannot be referenced from a static context
        outerStaticMethod();
        //outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
      */

      //  overwriting method must exist in prototype class
      public void innerInstanceMethod() {
        System.out.println(" 從 覆寫的 物件方法innerInstanceMethod,我可以:");
        System.out.println("  存取 " + outerStaticAttribute);
        System.out.println("  存取 " + outerInstanceAttribute);
        //System.out.println( "  存取 舊有私密 " + innerStaticAttribute);
        //  innerStaticAttribute has private access in InMethodUnnamedClass
        System.out.println("  存取 舊有公開 " + innerStaticAttribute2);
        //System.out.println( "  存取 添加私密 " + innerStaticAttribute3);
        //System.out.println( "  存取 " + innerInstanceAttribute);
        //  innerInstanceAttribute has private access in InMethodUnnamedClass
        System.out.println("  存取 舊有公開 " + innerInstanceAttribute2);
        System.out.println("  存取 添加私密 " + innerInstanceAttribute3);
        outerStaticMethod();
        outerInstanceMethod();
        //  non-static method cannot be referenced from a static context
      }
    };

    imuc.innerStaticMethod();
    imuc.innerInstanceMethod();
  }

  // 類別內具名靜態類別
  public static class InClassStaticClass {
    private static String innerStaticAttribute = "內部類別之類別屬性innerStaticAttribute";
    private String innerInstanceAttribute = "內部類別之物件屬性innerInstanceAttribute";

    public InClassStaticClass() {
      System.out.println("我是<類別內具名靜態類別InClassStaticClass>物件,擁有");
      System.out.println("\t類別屬性innerStaticAttribute");
      System.out.println("\t物件屬性innerInstanceAttribute");
      System.out.println("\t類別方法innerStaticMethod");
      System.out.println("\t物件方法innerInstanceMethod");
    }

    public static void innerStaticMethod() {
      System.out.println(" 從類別方法innerStaticMethod,我可以:");
      System.out.println("  存取 " + outerStaticAttribute);
      //System.out.println( "  存取 " + outerInstanceAttribute);
      //  non-static variable cannot be referenced from a static context
      System.out.println("  存取 " + innerStaticAttribute);
      //System.out.println( "  存取 " + innerInstanceAttribute);
      //  non-static variable cannot be referenced from a static context
      outerStaticMethod();
      //outerInstanceMethod();
      //  non-static method cannot be referenced from a static context
    }

    public void innerInstanceMethod() {
      System.out.println(" 從物件方法innerInstanceMethod,我可以:");
      System.out.println("  存取 " + outerStaticAttribute);
      //System.out.println( "  存取 " + outerInstanceAttribute);
      //  non-static variable cannot be referenced from a static context
      System.out.println("  存取 " + innerStaticAttribute);
      System.out.println("  存取 " + innerInstanceAttribute);
      outerStaticMethod();
      //outerInstanceMethod();
      //  non-static method cannot be referenced from a static context
    }
  }

  // 類別內具名非靜態類別
  public class InClassInstanceClass {
    //private static String innerStaticAttribute = "內部類別之類別屬性";
    //  inner classes cannot have static declarations
    private String innerInstanceAttribute = "內部類別之物件屬性innerInstanceAttribute";

    public InClassInstanceClass() {
      System.out.println("我是<類別內具名非靜態類別InClassInstanceClass>物件,擁有");
      System.out.println("\tx類別屬性");
      System.out.println("\t物件屬性innerInstanceAttribute");
      System.out.println("\tx類別方法");
      System.out.println("\t物件方法innerInstanceMethod");
    }

    //public static void innerStaticMethod()
    //  inner classes cannot have static declarations
    /*
    {
      System.out.println( "從類別方法,我可以:");
      System.out.println( " 存取 " + outerStaticAttribute);
      //System.out.println( " 存取 " + outerInstanceAttribute);
      //   non-static variable cannot be referenced from a static context
      //System.out.println( " 存取 " + innerStaticAttribute);
      System.out.println( " 存取 " + innerInstanceAttribute);
      outerStaticMethod();
      //outerInstanceMethod();
      //  non-static method cannot be referenced from a static context
    }
    */

    public void innerInstanceMethod() {
      System.out.println(" 從物件方法innerInstanceMethod,我可以:");
      System.out.println("  存取 " + outerStaticAttribute);
      System.out.println("  存取 " + outerInstanceAttribute);
      //System.out.println( "  存取 " + innerStaticAttribute);
      System.out.println("  存取 " + innerInstanceAttribute);
      outerStaticMethod();
      outerInstanceMethod();
    }
  }
}

class InMethodUnnamedClass {
  private static String innerStaticAttribute = "內部類別之類別屬性innerStaticAttribute";
  public static String innerStaticAttribute2 = "內部類別之類別屬性innerStaticAttribute2";
  //  inner classes cannot have static declarations
  private String innerInstanceAttribute = "內部類別之物件屬性innerInstanceAttribute";
  public String innerInstanceAttribute2 = "內部類別之物件屬性innerInstanceAttribute2";

  public InMethodUnnamedClass() {
    System.out.println(this.toString());
  }

  public String toString() {
    String text = "";

    text = text + "我是<方法內匿名類別InMethodUnnamedClass>物件,擁有\n";
    text = text + "\t類別屬性innerStaticAttribute,2\n";
    text = text + "\t物件屬性innerInstanceAttribute,2\n";
    text = text + "\t類別方法innerStaticMethod\n";
    text = text + "\t物件方法innerInstanceMethod";

    return text;
  }

  public static void innerStaticMethod() {
    System.out.println(" 從類別方法innerStaticMethod,我可以:");
    //System.out.println( "  存取 " + outerStaticAttribute);
    //System.out.println( "  存取 " + outerInstanceAttribute);
    //  non-static variable cannot be referenced from a static context
    System.out.println("  存取 私密 " + innerStaticAttribute);
    System.out.println("  存取 公開 " + innerStaticAttribute2);
    //outerStaticMethod();
    //outerInstanceMethod();
    //  non-static method cannot be referenced from a static context
  }

  public void innerInstanceMethod() {
    System.out.println(" 從物件方法innerInstanceMethod,我可以:");
    //System.out.println( "  存取 " + outerStaticAttribute);
    //System.out.println( "  存取 " + outerInstanceAttribute);
    //  non-static variable cannot be referenced from a static context
    System.out.println("  存取 私密 " + innerStaticAttribute);
    System.out.println("  存取 公開 " + innerStaticAttribute2);
    System.out.println("  存取 私密 " + innerInstanceAttribute);
    System.out.println("  存取 公開 " + innerInstanceAttribute2);
    //outerStaticMethod();
    //outerInstanceMethod();
    //  non-static method cannot be referenced from a static context
  }
}

public class Inner {
  public static void main(String args[]) {
    OuterClass oc = new OuterClass();

    // 使用類別內具名靜態類別
    System.out.println("\n1.使用類別內具名靜態類別...");
    // 建立<類別內具名靜態類別>之物件
    OuterClass.InClassStaticClass oc_icsc = new OuterClass.InClassStaticClass();

    OuterClass.InClassStaticClass.innerStaticMethod();
    oc_icsc.innerInstanceMethod();


    // 使用類別內具名非靜態類別
    //   要使用類別內具名靜態類別,需先建立其外部類別之物件
    System.out.println("\n2.使用類別內具名非靜態類別...");
    OuterClass.InClassInstanceClass oc_icic = oc.new InClassInstanceClass();
    //oc_icic.innerStaticMethod();
    oc_icic.innerInstanceMethod();

    // 使用方法內具名類別
    System.out.println("\n3.使用類別方法內具名靜態類別...");
    OuterClass.outerStaticMethod2();

    System.out.println("\n4.使用物件方法內具名非靜態類別...");
    oc.outerInstanceMethod2();

    // 使用方法內具匿名類別
    System.out.println("\n5.使用類別方法內匿名靜態類別...");
    OuterClass.outerStaticMethod3();

    System.out.println("\n6.使用物件方法內匿名非靜態類別...");
    oc.outerInstanceMethod3();
  }
}

沒有留言: