【Java工程师之路】[1-2.5]Java面向对象详解4

内部类

内部类Inner Class
  将相关的类组织在一起,从而降低了命名空间的混乱。
  一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。
  Java中的内部类共分为四种:
  
静态内部类static inner class (also called nested class)
  成员内部类member inner class
  局部内部类local inner class
  匿名内部类anonymous inner class
 
静态内部类Static Inner Class
  最简单的内部类形式。
  类定义时加上static关键字。
  不能和外部类有相同的名字。
  被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。
  只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
  生成静态内部类对象的方式为:
  OuterClass.InnerClass inner = new OuterClass.InnerClass();
  静态内部类使用代码:

[java]  view plain copy
  1. package com.learnjava.innerclass;  
  2.     class StaticInner  
  3. {  
  4.     private static int a = 4;  
  5.     // 静态内部类  
  6.     public static class Inner  
  7.     {  
  8.         public void test()  
  9.         {  
  10.             // 静态内部类可以访问外部类的静态成员  
  11.             // 并且它只能访问静态的  
  12.             System.out.println(a);  
  13.         }  
  14.     }  
  15. }  
  16.   
  17. public class StaticInnerClassTest  
  18. {  
  19.     public static void main(String[] args)  
  20.     {  
  21.         StaticInner.Inner inner = new StaticInner.Inner();  
  22.         inner.test();  
  23.     }  
  24. }  


成员内部类Member Inner Class
  成员内部类也是定义在另一个类中,但是定义时不用static修饰。
  成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。
  成员内部类就像一个实例变量。
  它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
  在外部类里面创建成员内部类的实例:
  this.new Innerclass();
  在外部类之外创建内部类的实例:
  (new Outerclass()).new Innerclass();
  在内部类里访问外部类的成员:
  Outerclass.this.member
  详情见代码例子:

[java]  view plain copy
  1. package com.learnjava.innerclass;  
  2.   
  3. class MemberInner  
  4. {  
  5.     private int d = 1;  
  6.     private int a = 2;  
  7.   
  8.     // 定义一个成员内部类  
  9.     public class Inner2  
  10.     {  
  11.         private int a = 8;  
  12.   
  13.         public void doSomething()  
  14.         {  
  15.             // 直接访问外部类对象  
  16.             System.out.println(d);  
  17.             System.out.println(a);// 直接访问a,则访问的是内部类里的a  
  18.   
  19.             // 如何访问到外部类里的a呢?  
  20.             System.out.println(MemberInner.this.a);  
  21.         }  
  22.   
  23.     }  
  24.   
  25. }  
  26.   
  27. public class MemberInnerClassTest  
  28. {  
  29.   
  30.     public static void main(String[] args)  
  31.     {  
  32.   
  33.         // 创建成员内部类的对象  
  34.         // 需要先创建外部类的实例  
  35.         MemberInner.Inner2 inner = new MemberInner().new Inner2();  
  36.   
  37.         inner.doSomething();  
  38.     }  
  39. }</span>  


局部内部类Local Inner Class
  局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
  像局部变量一样,不能被public, protected, private和static修饰。
  只能访问方法中定义的final类型的局部变量。
  局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。

[java]  view plain copy
  1. package com.learnjava.innerclass;  
  2.   
  3. class LocalInner  
  4. {  
  5.     int a = 1;  
  6.   
  7.     public void doSomething()  
  8.     {  
  9.         int b = 2;  
  10.         final int c = 3;  
  11.         // 定义一个局部内部类  
  12.         class Inner3  
  13.         {  
  14.             public void test()  
  15.             {  
  16.                 System.out.println("Hello World");  
  17.                 System.out.println(a);  
  18.   
  19.                 // 不可以访问非final的局部变量  
  20.                 // error: Cannot refer to a non-final variable b inside an inner  
  21.                 // class defined in a different method  
  22.                 // System.out.println(b);  
  23.   
  24.                 // 可以访问final变量  
  25.                 System.out.println(c);  
  26.             }  
  27.         }  
  28.   
  29.         // 创建局部内部类的实例并调用方法  
  30.         new Inner3().test();  
  31.     }  
  32. }  
  33.   
  34. public class LocalInnerClassTest  
  35. {  
  36.     public static void main(String[] args)  
  37.     {  
  38.         // 创建外部类对象  
  39.         LocalInner inner = new LocalInner();  
  40.         // 调用外部类的方法  
  41.         inner.doSomething();  
  42.     }  
  43.   
  44. }</span>  


 匿名内部类Anonymous Inner Class
  匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。
  匿名内部类隐式地继承了一个父类或者实现了一个接口。
  匿名内部类使用得比较多,通常是作为一个方法参数。

[java]  view plain copy
  1. package com.learnjava.innerclass;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class AnonymouseInnerClass  
  6. {  
  7.   
  8.     @SuppressWarnings("deprecation")  
  9.     public String getDate(Date date)  
  10.     {  
  11.         return date.toLocaleString();  
  12.   
  13.     }  
  14.   
  15.     public static void main(String[] args)  
  16.     {  
  17.         AnonymouseInnerClass test = new AnonymouseInnerClass();  
  18.   
  19.         // 打印日期:  
  20.         String str = test.getDate(new Date());  
  21.         System.out.println(str);  
  22.         System.out.println("----------------");  
  23.   
  24.         // 使用匿名内部类  
  25.         String str2 = test.getDate(new Date()  
  26.         {  
  27.         });// 使用了花括号,但是不填入内容,执行结果和上面的完全一致  
  28.             // 生成了一个继承了Date类的子类的对象  
  29.         System.out.println(str2);  
  30.         System.out.println("----------------");  
  31.   
  32.         // 使用匿名内部类,并且重写父类中的方法  
  33.         String str3 = test.getDate(new Date()  
  34.         {  
  35.   
  36.             // 重写父类中的方法  
  37.             @Override  
  38.             @Deprecated  
  39.             public String toLocaleString()  
  40.             {  
  41.                 return "Hello: " + super.toLocaleString();  
  42.             }  
  43.   
  44.         });  
  45.   
  46.         System.out.println(str3);  
  47.     }  
  48. }</span>  

生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。
Swing中使用内部类的例子如下:

[java]  view plain copy
  1. package com.learnjava.innerclass;  
  2.   
  3. import java.awt.event.ActionEvent;  
  4. import java.awt.event.ActionListener;  
  5. import java.awt.event.WindowAdapter;  
  6. import java.awt.event.WindowEvent;  
  7.   
  8. import javax.swing.JButton;  
  9. import javax.swing.JFrame;  
  10.   
  11. public class SwingTest  
  12. {  
  13.     public static void main(String[] args)  
  14.     {  
  15.         JFrame frame = new JFrame("JFrame");  
  16.         JButton button = new JButton("JButton");  
  17.   
  18.         button.addActionListener(new ActionListener()  
  19.         {  
  20.             // new出来一个实现了ActionListener接口的类的实例  
  21.   
  22.             @Override  
  23.             public void actionPerformed(ActionEvent arg0)  
  24.             {  
  25.                 System.out.println("Hello World");  
  26.   
  27.             }  
  28.         });  
  29.   
  30.         //加入按钮  
  31.         frame.getContentPane().add(button);  
  32.   
  33.         //设置关闭行为  
  34.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  35.   
  36.         frame.setSize(200200);  
  37.           
  38.         frame.addWindowListener(new WindowAdapter()  
  39.         {  
  40.             //也可以使用继承了适配器类的匿名内部类  
  41.             @Override  
  42.             public void windowClosing(WindowEvent e)  
  43.             {  
  44.               
  45.                 System.out.println("Closing");  
  46.                 System.exit(0);  
  47.             }  
  48.         });  
  49.         frame.setVisible(true);  
  50.     }  
  51.   
  52. }</span>  

你可能感兴趣的:(【Java工程师之路】[1-2.5]Java面向对象详解4)