匿名类、内部类、匿名内部类

前端时间在写.net项目中,一直错将.cs里的两个class当作内部类,原来是一个文件里的两个类而已,这让我想起了Java中的内部类,比较内部类,那么还有两个类,那就是匿名类和匿名内部类。今天我想就Java中的这三种类进行个比较。

我们知道在Java语言规范中可以做很多事,例如一个类或一个接口中可以声明一个类或接口,在一个方法中可以声明一个类,类与接口声明可以嵌套任意深度等。

 

匿名类:

      1、new <类或接口><类的主体>,匿名类的声明是在编译时进行的,实例化是在运行时进行的,所以在for循环中一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。

      2、如果要执行的对象需要一个对象,但却不值得创建全新的对象(可能是因为该对象只在一个方法内部使用),在这个时候使用匿名类就会非常合适,所以说,匿名类一般会在swing程序中快速创建事件处理程序。

Java代码  收藏代码

  1. firstButton.addActionListener(new ActionListener() {  
  2.         @Override  
  3.         public void actionPerformed(ActionEvent e) {  
  4.             getTxtValue().setText("第一个按钮触发的事件!");  
  5.         }  
  6.     });   

       3、从技术上说,匿名类可以被看作非静态的内部类,所以他们具有方法内部声明的非静态内部类相同的权限和限制。

 

 

内部类:

内部类顾名思义就是在一个类的内部还有一个类

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class InnerClassDemo {  
  9.     public static void main(String[] args) {  
  10.         new Outer().fun();  
  11.     }  
  12. }  
  13.   
  14. class Outer {  
  15.   
  16.     private String name = "Hello 内部类";  
  17.   
  18.     class Inner {  
  19.         public void print() {  
  20.             System.out.println("name = " + name);  
  21.   
  22.         }  
  23.     };  
  24.   
  25.     public void fun() {  
  26.         new Inner().print();  
  27.     }  
  28. }  

 

 内部类生成的.class文件名为:Outer$Inner.class,从上面的结构发现内部类的的缺点是“结构非常的混乱”。

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class InnerClassDemo02 {  
  9.     public static void main(String[] args) {  
  10.         new Outer02().fun();  
  11.     }  
  12. }  
  13.   
  14. class Outer02 {  
  15.   
  16.     private String name = "Hello 内部类";  
  17.   
  18.     public void fun() {  
  19.         new Inner02(this).print();  
  20.     }  
  21.   
  22.     public String getName() {  
  23.   
  24.         return this.name;  
  25.     }  
  26. };  
  27.   
  28. class Inner02 {  
  29.     private Outer02 out;  
  30.   
  31.     public Inner02(Outer02 out) {  
  32.         this.out = out;  
  33.     }  
  34.   
  35.     public void print() {  
  36.         System.out.println("name = " + this.out.getName());  
  37.   
  38.     }  
  39. };  

 从上可以看出内部类的优点是“可以方便的访问外部类中的私有成员”;

如果要在外部直接使用内部类的实例化对象:

      外部类.内部类 内部类对象 = 外部类实例.new 内部类实例();

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang  2012-1-11 
  5.  * 
  6.  *  Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class InnerClassDemo03 {  
  9.     public static void main(String[] args) {  
  10.         Outer03 out = new Outer03();//外部类实例  
  11.         Outer03.Inner inner = out.new Inner();//实例化内部类对象  
  12.         inner.print();  
  13.     }  
  14. }  
  15. class Outer03{  
  16.     private String name = "Hello 内部类";  
  17.     class Inner {  
  18.         public void print() {  
  19.             System.out.println("name = " + name);  
  20.         }  
  21.     }  
  22. }  

 

 一个内部类如果使用static关键字声明的话,则此内部类就将成为外部类,可以直接通过外部类.内部类的形式访问

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class InnerClassDemo04 {  
  9.     public static void main(String[] args) {  
  10.         Outer04.Inner inner = new Outer04.Inner();// 实例化内部类对象  
  11.         inner.print();  
  12.     }  
  13. }  
  14.   
  15. class Outer04 {  
  16.     private static String name = "Hello 内部类";  
  17.   
  18.     static class Inner {  
  19.         public void print() {  
  20.             System.out.println("name = " + name);  
  21.         }  
  22.     }  
  23. }  

 

 内部类可以在任意的地方使用,例如方法中声明

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class InnerClassDemo05 {  
  9.     public static void main(String[] args) {  
  10.         new Outer05().fun();  
  11.     }  
  12. }  
  13.   
  14. class Outer05 {  
  15.     private static String name = "Hello 内部类";  
  16.   
  17.     public void fun() {  
  18.         class Inner {  
  19.             public void print() {  
  20.                 System.out.println("name = " + name);  
  21.             }  
  22.         }  
  23.         new Inner().print();  
  24.     }  
  25. }  

 

 在方法中定义的内部类,可以直接访问外部类中的各个成员,但是如果要访问方法中的参数,则需要在参数上加上final关键字声明;

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class InnerClassDemo06 {  
  9.     public static void main(String[] args) {  
  10.         new Outer06().fun(20);  
  11.     }  
  12. }  
  13.   
  14. class Outer06 {  
  15.     private static String name = "Hello 内部类";  
  16.   
  17.     public void fun(final int temp) {  
  18.         class Inner {  
  19.             public void print() {  
  20.                 System.out.println("temp = " + temp);  
  21.                 System.out.println("name = " + name);  
  22.             }  
  23.         }  
  24.         new Inner().print();  
  25.     }  
  26. }  

 匿名类与内部的联系与区别:

按所在位置可以分为两大类:

      1、在类的方法中

                     特点:

                              a、可以访问宿主类的所有元素 ;

                              b、保存宿主类对象的引用,创建对象时必须有宿主类对象;

                              c、 不能有静态数据;

继续划分:

                             A、本地内部类;

                             B、匿名内部类

 两者的区别在于本地内部类有构造方法,而匿名内部类只能实例初始化;

      2、在类或接口作用域中;

                     继续划分:

                            A、普通内部类

                            B、静态内部类

 

 

匿名内部类:

匿名内部类是在抽象类和接口的基础之上发展起来的。

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class NoNameClass01 {  
  9.     public static void main(String[] args) {  
  10.         new X().fun2();  
  11.     }  
  12. }  
  13.   
  14. interface A {  
  15.     public void fun();  
  16. }  
  17.   
  18. class B implements A {  
  19.     public void fun() {  
  20.   
  21.         System.out.println("Hello 准备匿名内部类");  
  22.     }  
  23. }  
  24.   
  25. class X {  
  26.     public void fun1(A a) {  
  27.         a.fun();  
  28.     }  
  29.   
  30.     public void fun2() {  
  31.         this.fun1(new B());  
  32.     }  
  33. }  

 通过上面的Demo,如果现在假设B类只使用一次,那么还有必要将其定义成一个单独的类么?

 呵呵,此时就可以使用匿名内部类:

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class NoNameClass02 {  
  9.   
  10.     public static void main(String[] args) {  
  11.         new XX().fun2();  
  12.     }  
  13. }  
  14.   
  15. interface AA {  
  16.     public void fun();  
  17. }  
  18.   
  19. class XX {  
  20.     public void fun1(AA a) {  
  21.         a.fun();  
  22.     }  
  23.     public void fun2() {  
  24.         this.fun1(new AA() {  
  25.             public void fun() {  
  26.                 System.out.println("Hello 准备匿名内部类");  
  27.             }  
  28.         });  
  29.     }  
  30. }  

 其实在真正的项目开发中匿名内部类使用的非常之少,一般在Java的图形界面和现在的Android中使用的比较多点。

 

 最后给一个内部类实现的简单链表:

Java代码  收藏代码

  1. package com.iflytek.innerclass;  
  2.   
  3. /** 
  4.  * @author xudongwang 2012-1-11 
  5.  *  
  6.  *         Email:xdwangiflytek@gmail.com 
  7.  */  
  8. public class LinkDemo {  
  9.     public static void main(String args[]) {  
  10.         Link link = new Link();  
  11.         link.add("A");  
  12.         link.add("B");  
  13.         link.add("C");  
  14.         link.add("D");  
  15.         link.add("E");  
  16.         link.print();  
  17.     }  
  18. };  
  19.   
  20. class Link {  
  21.     class Node {  
  22.         private String name;  
  23.         private Node next; // 单向链表,每个节点指向下一个节点  
  24.   
  25.         public Node(String name) {  
  26.             this.name = name; // 通过构造方法为name属性赋值  
  27.         }  
  28.   
  29.         public void addNode(Node newNode) { // 增加节点  
  30.             if (this.next == null) {  
  31.                 this.next = newNode; // 保存节点  
  32.             } else {  
  33.                 this.next.addNode(newNode); // 继续向下查找  
  34.             }  
  35.         }  
  36.   
  37.         public void printNode() { // 输出节点  
  38.             System.out.println(this.name);  
  39.             if (this.next != null) { // 此节点之后还存在其他的节点  
  40.                 this.next.printNode();  
  41.             }  
  42.         }  
  43.     };  
  44.   
  45.     private Node root; // 链表的头  
  46.   
  47.     public void add(String name) { // 增加节点  
  48.         Node newNode = new Node(name); // 定义一个新的节点  
  49.         /* 
  50.          * 如果是第一个节点,则肯定是根节点, 如果是第二个节点,则肯定放在根节点next中 如果是第三个节点,则肯定放在第二个节点的next中 
  51.          */  
  52.         if (this.root == null) {  
  53.             this.root = newNode; // 将第一个节点设置成根节点  
  54.         } else {  
  55.             // 肯定要放在最后一个节点之后  
  56.             // 通过节点.next来不断的判断  
  57.             this.root.addNode(newNode);  
  58.         }  
  59.     }  
  60.   
  61.     public void print() {  
  62.         if (this.root != null) { // 如果根节点为空了,则没有任何内容  
  63.             this.root.printNode();  
  64.         }  
  65.     }  
  66. };  
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页