关于JAVA中匿名内部类的使用

匿名内部类:没有名字的类。

1.匿名内部类只能使用一次,它通常用来简化代码编写。

2.匿名内部类不能重复使用。

3.从定义看,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。

4.匿名内部类不等定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块。


Eg:

  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 820;  
  14.     }  
  15.    public String getName(){  
  16.       return "衣服";  
  17.    }  
  18.   });  
  19.  }  
  20. }  
上面程序中的TestAnonymous类定义了一个test方法,该方法需要一个Product对象作为参数,但Product只是一个接口, 无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法---如果这个Product接口实现类需要重复 使用,则应该经该实现类定义一个独立类;如果这Product接口实现类只需一次使用,则可采用上面程序中的方式,定义 一个匿名内部类。
    正如上面程序中看到,定义匿名类不需要class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。上面 粗体字代码部分就是匿名类的类体部分。
    由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的所有抽象方法。 对于上面创建Product实现类对象的代码,可以拆分成如下代码:

  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接口名后的括号里不能传入参数值。
   但如果通过继承父类来创建匿名内部类是,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的形参 列表。

  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修饰符来修饰外部类的局部变量, 否则系统将报错。

  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修饰符修饰,所以粗体字代码将引起编译异常。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值