Java之学习笔记(15)-------------内部类


一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。

  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. 静态内部类使用测试  
  2.   
  3. package com.learnjava.innerclass;  
  4.   
  5. class StaticInner  
  6. {  
  7.     private static int a = 4;  
  8.   
  9.     // 静态内部类  
  10.     public static class Inner  
  11.     {  
  12.         public void test()  
  13.         {  
  14.             // 静态内部类可以访问外部类的静态成员  
  15.             // 并且它只能访问静态的  
  16.             System.out.println(a);  
  17.         }  
  18.   
  19.     }  
  20. }  
  21.   
  22. public class StaticInnerClassTest  
  23. {  
  24.   
  25.     public static void main(String[] args)  
  26.     {  
  27.         StaticInner.Inner inner = new StaticInner.Inner();  
  28.         inner.test();  
  29.     }  
  30. }  


 

成员内部类Member Inner Class

  成员内部类也是定义在另一个类中,但是定义时不用static修饰。

  成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。

  成员内部类就像一个实例变量。

  它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以

  在外部类里面创建成员内部类的实例:

  this.new Innerclass();

  在外部类之外创建内部类的实例:

  (new Outerclass()).new Innerclass();

  在内部类里访问外部类的成员:

  Outerclass.this.member

  详情见代码例子:

成员内部类使用测试
package com.learnjava.innerclass;

class MemberInner
{
    private int d = 1;
    private int a = 2;

    // 定义一个成员内部类
    public class Inner2
    {
        private int a = 8;

        public void doSomething()
        {
            // 直接访问外部类对象
            System.out.println(d);
            System.out.println(a);// 直接访问a,则访问的是内部类里的a

            // 如何访问到外部类里的a呢?
            System.out.println(MemberInner.this.a);
        }

    }

}

public class MemberInnerClassTest
{

    public static void main(String[] args)
    {

        // 创建成员内部类的对象
        // 需要先创建外部类的实例
        MemberInner.Inner2 inner = new MemberInner().new Inner2();

        inner.doSomething();
    }
}

 

局部内部类Local Inner Class

  局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。

  像局部变量一样,不能被public, protected, private和static修饰。

  只能访问方法中定义的final类型的局部变量。

  局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。

 

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


 

匿名内部类Anonymous Inner Class

  匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。

  匿名内部类隐式地继承了一个父类或者实现了一个接口

  匿名内部类使用得比较多,通常是作为一个方法参数。

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


生成的.class文件中,匿名类会生成OuterClass$1.class文件,数字根据是第几个匿名类而类推。

  Swing中使用内部类的例子如下:

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

良心的公众号,更多精品文章,不要忘记关注哈

《Android和Java技术栈》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值