1. 程式人生 > >淺析Java內部類在GUI設計中的作用(2)

淺析Java內部類在GUI設計中的作用(2)

四、方法內部類

方法內部類只在該方法內部可見,方法內部類可以定義在方法中的任何位置。

  1. /**   
  2. * 內部類實現介面   
  3.  
  4. * @author leizhimin 2009-7-17 14:57:50   
  5. */
  6. public class  Test2 {   
  7. public static void  main(String[] args) {   
  8.                 Outer outer =  new  Outer();   
  9.                 Foo f = outer.genFoo();   
  10.                 Bar b = outer.genBar();   
  11.                 f.say();   
  12.                 b.readme();   
  13.         }   
  14. }   
  15. class  Outer {   
  16. public  Foo genFoo() {   
  17. //方法內的內部類 
  18. class  FooImpl  implements  Foo {   
  19. public void  say() {   
  20.                                 System.out.println( "say foo!" );   
  21.                         }   
  22.                 }   
  23. return new  FooImpl();   
  24.         }   
  25. public  Bar genBar() {   
  26.                 Bar b =  null ;   
  27. if  ( true ) {   
  28. //任意位置的內部類 
  29. class  BarImpl  implements  Bar {   
  30. public void  readme() {   
  31.                                         System.out.println( "say bar!"
    );   
  32.                                 }   
  33.                         }   
  34.                         b =  new  BarImpl();   
  35.                 }   
  36. return  b;   
  37.         }   
  38. }  

執行結果:

say foo!

say bar!

Process finished with exit code 0

五、匿名類

匿名類不給出類名,直接定義一個類,通常這個類實現了某種介面或者抽象。匿名類的訪問許可權更沒有討論價值了,看個例子就行了。

在一些多執行緒程式中比較常見,有點變態,呵呵。

  1. /**   
  2. * 匿名類.   
  3.  
  4. * @author leizhimin 2009-7-17 15:56:17   
  5. */
  6. public class  Test3 {   
  7. public  Foo f =  new  Foo() {   
  8. public void  say() {   
  9.                         System.out.println( "O(∩_∩)O哈哈~!" );   
  10.                 }   
  11.         };   
  12. public  Foo test() {   
  13. return new  Foo() {   
  14. public void  say() {   
  15.                                 System.out.println( "say foo!" );   
  16.                         }   
  17.                 };   
  18.         }   
  19. public static void  main(String[] args) {   
  20.                 Test3 t =  new  Test3();   
  21.                 t.f.say();   
  22.                 t.test().say();   
  23.         }   
  24. }   
  25. interface  Foo {   
  26. void  say();   
  27. }  

執行結果:

say foo!

  1. Process finished with exit code  0
  2. /**   
  3. * 普通類的匿名初始化   
  4.  
  5. * @author leizhimin 2009-7-17 16:13:31   
  6. */
  7. public class  Fk {   
  8. private  String x;   
  9. public  Fk(String x) {   
  10. this .x = x;   
  11.         }   
  12. @Override
  13. public  String toString() {   
  14. return "Fk{"  +   
  15. "x='"  + x + '/ ''  +   
  16. '}' ;   
  17.         }   
  18. }   
  19. class  Test4 {   
  20. public  Fk hehe() {   
  21. //把後面的一對大括號去掉呢,呵呵 
  22. return new  Fk( "fk" ) {   
  23.                 };   
  24.         }   
  25. public static void  main(String[] args) {   
  26.                 Test4 t =  new  Test4();   
  27.                 Fk f = t.hehe();   
  28.                 System.out.println(f);   
  29.         }   
  30. }  

執行結果:

Fk{x='fk'}

Process finished with exit code 0

還有一個不得不提的經典例項,來自thining in java,有改動:

  1. interface  Service {   
  2. void  method1();   
  3. void  method2();   
  4. }   
  5. interface  ServiceFactory {   
  6.     Service getService();   
  7. }   
  8. class  Implementation1  implements  Service {   
  9. private  Implementation1() {}   
  10. public void  method1() {System.out.println( "Implementation1 method1" );}   
  11. public void  method2() {System.out.println( "Implementation1 method2" );}   
  12. public static  ServiceFactory factory =  new  ServiceFactory() {   
  13. public  Service getService() {   
  14. return new  Implementation1();   
  15.             }   
  16.         };   
  17. }   
  18. class  Implementation2  implements  Service {   
  19. private  Implementation2() {}   
  20. public void  method1() {System.out.println( "Implementation2 method1" );}   
  21. public void  method2() {System.out.println( "Implementation2 method2" );}   
  22. public static  ServiceFactory factory =  new  ServiceFactory() {   
  23. public  Service getService() {   
  24. return new  Implementation2();   
  25.             }   
  26.         };   
  27. }   
  28. public class  Factories {   
  29. public static void  serviceConsumer(ServiceFactory fact) {   
  30.         Service s = fact.getService();   
  31.         s.method1();   
  32.         s.method2();   
  33.     }   
  34. public static void  main(String[] args) {   
  35.         serviceConsumer(Implementation1.factory);   
  36.         serviceConsumer(Implementation2.factory);   
  37.     }   
  38. }  

這個應用給了我們很多思考,我就不說了,不同人看了會有不同的感受。

內部類的巧妙使用會讓你的程式碼很牛,如果要形容下,那就是:沒看懂的時候感覺神出鬼沒,看懂後感覺鬼斧神工。不過這些程式碼多了,別人想看懂都難,想 看懂你思路就難上加難了。呵呵!

六、靜態內部類

靜態內部類是static class型的內部類,這種內部類特點是:它不能訪問外部類的非靜態成員。要建立靜態內部類物件時候,也不需要外部類物件了,直接可以:

new 外部類名.內部類構造方法

來建立,給個例子:

  1. /**   
  2. * 靜態內部類   
  3.  
  4. * @author leizhimin 2009-7-17 16:53:05   
  5. */
  6. public class  Outer {   
  7. public static int  i = 500 ;   
  8. protected static class  Inner {   
  9. int  i = 100 ;   
  10.                 String name;   
  11.                 Inner(String name) {   
  12. this .name = name;   
  13.                 }   
  14. void  sayHello() {   
  15.                         System.out.println( "Hello "  + name);   
  16.                         Outer.i++;   
  17.                 }   
  18.         }   
  19. public  Inner genInner(String name) {   
  20. return new  Inner(name);   
  21.         }   
  22. }   
  23. class  Test {   
  24. public static void  main(String[] args) {   
  25.                 Outer.Inner in1 =  new  Outer.Inner( "1111" );   
  26.                 in1.sayHello();   
  27.                 System.out.println(Outer.i);   
  28.                 Outer.Inner in2 =  new  Outer().genInner( "2222" );   
  29.                 in2.sayHello();   
  30.                 System.out.println(Outer.i);   
  31.         }   
  32. }  

執行結果:

Hello 1111

501

Hello 2222

502

Process finished with exit code 0

七、介面內部類

介面內部類自動都是public static的,相當於為介面定義了一種變數型別,這在java的設計中就有使用,比如在HashMap中,就有:

static class Entry<K,V> implements Map.Entry<K,V>

下面我給個例子,

  1. /**   
  2. * 介面內部類   
  3.  
  4. * @author leizhimin 2009-7-17 17:20:28   
  5. */
  6. public interface  AInterface {   
  7. void  readme();   
  8. class  Inner1  implements  AInterface {   
  9. public void  readme() {   
  10.                         System.out.println( "我是一個介面內部類" );   
  11.                 }   
  12.         }   
  13. }   
  14. class  Main {   
  15. public static void  main(String[] args) {   
  16.                 AInterface.Inner1 in1 =  new  AInterface.Inner1();   
  17.                 in1.readme();   
  18.         }   
  19. }  

八、內部的類的巢狀

所謂內部類巢狀,就是內部類裡面再定義內部類。其實這種用法還真沒見過,試試寫個簡單例子看看吧:

  1. /**   
  2. * 巢狀內部類   
  3.  
  4. * @author leizhimin 2009-7-17 17:33:48   
  5. */
  6. public class  Outer {   
  7. private void  f0() {   
  8.                 System.out.println( "f0" );   
  9.         }   
  10. class  A {   
  11. private void  a() {   
  12.                         f0();   
  13.                         System.out.println( "a" );   
  14.                 }   
  15. class  B {   
  16. protected void  b() {   
  17.                                 a();   
  18.                                 System.out.println( "b" );   
  19.                         }   
  20.                 }   
  21.         }   
  22. }   
  23. class  Test{   
  24. public static void  main(String[] args) {   
  25.                 Outer o =  new  Outer();   
  26.                 Outer.A    a =     o. new  A();   
  27.                 Outer.A.B b = a. new  B();   
  28.                 b.b();   
  29.         }   
  30. }  

執行結果:

f0

a

b

Process finished with exit code 0

八、內部類的繼承

內部類的繼承,可以繼承內部類,也可以繼承外部類。

  1. /**   
  2. * 內部類的繼承,可以繼承內部類,也可以繼承外部類   
  3.  
  4. * @author leizhimin 2009-7-22 13:50:01   
  5. */
  6. public class  Outer {   
  7. class  Inner {   
  8. void  doSomething() {   
  9.                         System.out.println( "Inner doing ..." );   
  10.                 }   
  11.         }   
  12. class  Inner2  extends  Inner {   
  13. void  doSomething() {   
  14.                         System.out.println( "Inner2 doing ..." );   
  15.                 }   
  16. void  readme() {   
  17.                         System.out.println( "HeHe!" );   
  18.                 }   
  19.         }   
  20. }   
  21. class  Test {   
  22. public static void  main(String[] args) {   
  23.                 Outer outer =  new  Outer();   
  24.                 Outer.Inner in = outer. new  Inner();   
  25.                 Outer.Inner2 in2 = outer. new  Inner2();   
  26.                 in.doSomething();   
  27.                 in2.doSomething();   
  28.                 in2.readme();   
  29.         }   
  30. }  

執行結果:

Inner doing ...

Inner2 doing ...

HeHe!

Process finished with exit code 0

總結

內部類是Java中最複雜深奧的概念之一,而且內部類在訪問控制,修飾符,繼承,實現,抽象,序列化等等很多方面都是一個很讓人迷惑的問題,在實際 中,這些問題也許永遠沒機會沒時間搞清,但是一般說來,懂得以上的內部類的知識就足夠用了。

內部類的設計也許是彌補Java語言本身的先天不足吧,作為語言來說,這個特性太變態了點,難道就沒別的法了?

以上的總結完全是建立在實踐基礎上的,所列舉的例子也許偏頗,不能全面反映問題的本質,希望有興趣的博友多多發表自己的看法與觀點。

本文轉自 http://developer.51cto.com/art/201002/183375_1.htm

希望對有需要的朋友有幫助