匿名内部类精讲

el/2024/7/24 2:41:09

匿名内部类适合创建那种只需要一次使用的类,例如命令模式时所需要的Command对象。匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。
    定义匿名内部类的格式如下:

[java]  view plain copy
  1. new 父类构造器(参数列表)|实现接口()  
  2. {  
  3.  //匿名内部类的类体部分  
  4. }  
 

从上面定义可以看出,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。
 关于匿名内部类还有如下两条规则:
 1)匿名内部类不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建内部类的对象。因此不允许将匿名内部类
 定义成抽象类。
 2)匿名内部类不等定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,
 通过实例初始化块来完成构造器需要完成的事情。

 最常用的创建匿名内部类的方式是需要创建某个接口类型的对象,如下程序所示:

[java]  view plain copy
  1. interface Product{  
  2.    public double getPrice();  
  3.    public String getName();  
  4. }  
  5. public class TestAnonymous{  
  6.    public void test(Product p){  
  7.       System.out.println("购买了一个"+p.getName()+",花掉了"+p.getPrice());  
  8.   }  
  9.   public static void main(String[]args){  
  10.     TestAnonymous ta = new TestAnonymous();  
  11.     ta.test(new Product(){  
  12.         public double getPrice(){  
  13.             return 567;  
  14.         }  
  15.        public String getName(){  
  16.            return "AGP显卡";  
  17.        }  
  18.    });  
  19.   }  
  20. }  
 

上面程序中的TestAnonymous类定义了一个test方法,该方法需要一个Product对象作为参数,但Product只是一个接口,
无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法---如果这个Product接口实现类需要重复
使用,则应该经该实现类定义一个独立类;如果这个Product接口实现类只需一次使用,则可采用上面程序中的方式,定义
一个匿名内部类。
    正如上面程序中看到,定义匿名类不需要class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。上面
粗体字代码部分就是匿名类的类体部分。
 由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的所有抽象方法。
 对于上面创建Product实现类对象的代码,可以拆分成如下代码:

[java]  view plain copy
  1. class AnonymousProduct implements Product{  
  2.   public double getPrice(){  
  3.    return 567;  
  4.     }  
  5.   public String getName(){  
  6.    return "AGP显卡";  
  7.     }  
  8.  }  
  9.  ta.test(new AnonymousProduct());  
 

 当通过实现接口来创建匿名内部类时,匿名内部类也不能显示创建构造器,因此匿名内部类只有一个隐式的无参数构造
器,故new接口名后的括号里不能传入参数值。
    但如果通过继承父类来创建匿名内部类是,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的形参
列表。

 

 

 

[c-sharp]  view plain copy
  1. abstract class Device{  
  2.   private String name;  
  3.   public Device(){  
  4.   }  
  5.   public Device(String name){  
  6.    this.name = name;  
  7.   }  
  8.   public abstract double getPrice();  
  9.   //此处省略了name属性的setter和getter方法  
  10.  }  
  11.  public class AnonymousInner{  
  12.   public void test(Device d){  
  13.    System.out.println("购买了一个"+d.getName()+",花掉了"+d.getPrice());  
  14.   }  
  15.   public static void main(String[] args){  
  16.    AnonymousInner ai = new AnonymousInner();  
  17.    //调用有参数的构造器创建Device匿名实现类的对象  
  18.    ai.test(new Device("电子示波器"){  
  19.     public double getPrice(){  
  20.      return 67;  
  21.     }  
  22.    });  
  23.    //调用无参数的构造器创建Device匿名实现类的对象  
  24.    Device d = new Device(){  
  25.     //初始化块  
  26.     {  
  27.      System.out.println("匿名内部类的初始化块...");  
  28.     }  
  29.     //实现抽象方法  
  30.     public double getPrice(){  
  31.      return 56;  
  32.     }  
  33.     public Sting getName(){  
  34.      return "键盘";  
  35.     }  
  36.    };  
  37.    ai.test(d);  
  38.   }  
  39.  }  
 

上面程序创建了一个抽象父类Device,这个抽象父类里包含两个构造器:一个无参数的,一个有参数的。当创建以Device
为父类的匿名内部类时,即可以传入参数(如上面程序中第一段粗体字部分),也可以不传入参数(如上面程序中第二段粗体
字部分)。
 当创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法。如果有需要,也可以重写父类中的普通方法,如上面
程序的第二段粗体字代码部分,匿名内部类重写了抽象父类Device类的getName方法,其中getName方法并不是抽象方法。
    如果匿名内部类需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量,
否则系统将报错。

[java]  view plain copy
  1. interface A{  
  2.   void test();  
  3.  }  
  4.  public class TestA{  
  5.   public static void main(Strign[] args){  
  6.    int age = 0;  
  7.    A a = new A(){  
  8.     public void test(){  
  9.      //下面语句将提示错误:匿名内部类内访问局部变量必须使用final修饰  
  10.      System.out.println(age);  
  11.     }   
  12.    };  
  13.   }  
  14.  }  
 

 上面程序中粗体子代码是匿名内部类访问了外部类的局部变量,由于age变量没有使用final修饰符修饰,所以粗体字代码将
引起编译异常。


http://www.ngui.cc/el/5557273.html

相关文章

如何安装安装nginx软件--nginx的自动安装

去官网下包的安装教程,可以参考:(手动安装教程) http://blog.csdn.net/u011630575/article/details/48033431 自动安装nginx软件 第一步: sudo apt-get install nginx 第二步:安装结束 nginx常用命令…

linux下安装安装pcre configure: error: You need a C++ compiler for C++ support

linux下安装安装pcre-*.** ./configure --prefix/usr/local/pcre 出现以下错误 configure: error: You need a C compiler for C support 只需要安装gcc-c即可。 (1)命令:sudo apt-get install gcc;(2)命…

ubuntu下编译php扩展的时候报缺少pcre解决办法

命令:apt-get update 命令:apt-get install libpcre3 libpcre3-dev 刚刚在编译php扩展的时候,报缺少pcre错误。 当然是想通过apt-get这个命令解决问题了,不过搜索了网络,只找到了CentOS的yum命令: yum up…

ubuntu下nginx的安装教程(过程可能有点不同)

注: 过程可能有点不同,详细可以参照下一篇博客。 http://blog.csdn.net/u011630575/article/details/48103243 第一步: 去官网下载http://nginx.org/下载nginx;下载nginx; 第二步: 解压 tar -zxvf nginx…

nginx+php(fastcgi)安装教程

安装nginx见下一篇博客: http://blog.csdn.net/u011630575/article/details/48103243 基础阶段:(搭建php前奏) 安装包 libiconv-1.1.0.tar.gz libmcrypt-2.5.8.tar.gz mhash-0.9.3.tar.gz mcrypt-2.6.4.tar.gz 第一步&…

linux命令(1):wget命令

Linux系统中的wget是一个下载文件的工具,它用在命令行下。对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器。wget支持HTTP,HTTPS和FTP协议,可以使用HTTP代理。所谓的自动下载是指&#…

linux命令(2):gzip命令

减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。 gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用。gzip不仅可以用来压缩大的、较少使用的文件以…

Linux命令(3)打Patch的方法

作为程序员,了解diff&patch命 令是非常必要的。比如说我们发现某个项目有bug代码,而自己又没有svn的提交权限,那么此时最合适的解决方法就是用diff命令做一个补丁发给项目成员。项目成员通过patch命令可以立刻知道你的意图。有人会说直接…

linux命令(4)curl命令详解

对于windows用户如果用Cygwin模拟unix环境的话,里面没有带curl命令,要自己装,所以建议用Gow来模拟,它已经自带了curl工具,安装后直接在cmd环境中用curl命令就可,因为路径已经自动给你配置好了。 linux curl…

Ubuntu中安装zlib

命令:sudo apt-get install zlib1g-dev 说明: Ubuntu版本:13.10 zlib的官网打不开,apt-get insatll zlib也找不到软件包,貌似不在软件源里? 解决方法是打开ubuntu software center,搜索zlib&…