博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 匿名内部类
阅读量:4553 次
发布时间:2019-06-08

本文共 4405 字,大约阅读时间需要 14 分钟。

匿名内部类:  匿名内部类与正规的继承相比有些受限,因为匿名内部类既可以扩展类,也可以实现接口,但不能两者兼备,而且如果实现接口,也只能实现一个接口

一.contents()方法将返回值的生成与表示这个返回值的类的定义结合在一起!另外,这个类是匿名的,它没有名字,更糟糕的是,看起来似乎是你要创建一个Contents对象,但是然后(在到达语句结束的分号之前)你却说:"等一等,我想在这里插入一个类的定义."  下面代码用默认构造器来实现了接口Contents

//: 接口匿名类 //: innerclasses/Contents.javapackage object;public interface Contents {  int value();} ///:~//: innerclasses/Parcel7.java// Returning an instance of an anonymous inner class.package object;public class Parcel7 {  public Contents contents() {     return new Contents() { // Insert a class definition //这里用默认构造器实现了Contents的初始化      private int i = 11;      public int value() { return i; }    }; // Semicolon required in this case  }  public static void main(String[] args) {    Parcel7 p = new Parcel7();    Contents c = p.contents();  }} ///:~ //上面的Parcel7类是下面的Parcel7类的简化

//: innerclasses/Parcel7b.java

// Expanded version of Parcel7.java
  package object;
  public class Parcel7b {
  class MyContents implements Contents {
  private int i = 11;
  public int value() { return i; }
  }
  public Contents contents() { return new MyContents(); }
  public static void main(String[] args) {
  Parcel7b p = new Parcel7b();
  Contents c = p.contents();
  }
  } ///:~

 

二.如果需要一个有参数的构造器,该怎么办,只需要简单地传递合适的参数给基类的构造器即可,下面用带参构造器实现了有具体实现的普通类,这里将X传进了new Wrapping(x),尽管Wrapping只是一个具有具体实现的普通类,但它还是被其导出类当作公共的"接口"来使用:

//: innerclasses/Wrapping.javapackage object;public class Wrapping {  private int i;  public Wrapping(int x) { i = x; }  public int value() { return i; }} ///:~//: innerclasses/Parcel8.java// Calling the base-class constructor.package object;public class Parcel8 {  public Wrapping wrapping(int x) {    // Base constructor call:    return new Wrapping(x) { // Pass constructor argument. \\x值被传递给Wrapping(int x)构造器      public int value() {        return super.value() * 47; //这里调用了Wrapping类里面的value()方法      }    }; // Semicolon required //这里的分号不是用来标记内部类的结束,实际上,它标记的是表达式的结束  }  public static void main(String[] args) {    Parcel8 p = new Parcel8();    Wrapping w = p.wrapping(10);  }} ///:~

在匿名类中定义字段时,还能够对其执行初始化操作,如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用时final的(从jdk1.8开始可以不用final了)

//: innerclasses/Destination.javapackage object;public interface Destination {  String readLabel();} ///:~//: innerclasses/Parcel9.java// An anonymous inner class that performs// initialization. A briefer version of Parcel5.java.package object;public class Parcel9 {  // Argument must be final to use inside  // anonymous inner class:  public Destination destination(final String dest) {//这里书上说要final 但从jdk1.8开始可以不用final了    return new Destination() {      private String label = dest;      public String readLabel() { return label; }    };  }  public static void main(String[] args) {    Parcel9 p = new Parcel9();    Destination d = p.destination("Tasmania");  }} ///:~

在匿名类中不可能有构造器(因为它没有名字!),但通过实例初始化,就能够达到为匿名内部类创建一个构造器的效果.

//: innerclasses/AnonymousConstructor.java// Creating a constructor for an anonymous inner class.package object;import static net.mindview.util.Print.*;abstract class Base {  public Base(int i) {    print("Base constructor, i = " + i);  }  public abstract void f();}    public class AnonymousConstructor {  public static Base getBase(int i) {    return new Base(i) {  //这里调用了基类(abstract)Base的构造器      { print("Inside instance initializer"); }      public void f() {        print("In anonymous f()");      }    };  }  public static void main(String[] args) {    Base base = getBase(47);    base.f();  }} /* Output:Base constructor, i = 47Inside instance initializerIn anonymous f()*///:~

下面是带实例初始化的"parcel"形式

//: innerclasses/Destination.javapackage object;public interface Destination {  String readLabel();} ///:~//: innerclasses/Parcel10.java// Using "instance initialization" to perform// construction on an anonymous inner class.package object;public class Parcel10 {  public Destination  destination(final String dest, final float price) {    return new Destination() {      private int cost;      // Instance initialization for each object:      {        cost = Math.round(price);        if(cost > 100)          System.out.println("Over budget!");      }      private String label = dest;      public String readLabel() { return label; }    };  }      public static void main(String[] args) {    Parcel10 p = new Parcel10();    Destination d = p.destination("Tasmania", 101.395F);  }} /* Output:Over budget!*///:~

 

转载于:https://www.cnblogs.com/jiangfeilong/p/10224233.html

你可能感兴趣的文章
WPF MVVM框架PRISM
查看>>
UVa 208 - Firetruck <双向DFS>
查看>>
winform treeview绑定数据 DOM操作
查看>>
linux centos oracle11g 单机完整部署分享
查看>>
hznu
查看>>
《JAVA与模式》之模板方法模式 (转)
查看>>
JavaSE:八种基本数据类型
查看>>
JumpServer 堡垒机 指南
查看>>
IOS UIApplication和AppDelegate 关系
查看>>
HTML5新表单元素
查看>>
Linux CentOS下Python+robot framework环境搭建
查看>>
36: Same Tree
查看>>
bzoj 3671: [Noi2014]随机数生成器【模拟+贪心】
查看>>
MVC html.Telerik 开元控件在线文档
查看>>
题目1545:奇怪的连通图
查看>>
冲刺周期第九天
查看>>
C#操作SQL Server数据库
查看>>
对linux中source,fork,exec的理解以及case的 使用
查看>>
[BZOJ 1816] [Cqoi2010] 扑克牌 【二分答案】
查看>>
懒加载图片
查看>>