zoukankan      html  css  js  c++  java
  • java 匿名内部类

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

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

    //: 接口匿名类
    //
    : innerclasses/Contents.java package 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.java
    package 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.java
    package 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 = 47
    Inside instance initializer
    In anonymous f()
    *///:~

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

    //: innerclasses/Destination.java
    package 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!
    *///:~
  • 相关阅读:
    C++ 函数返回数组指针的问题
    cmake 静态调用 c++ dll 的类的一个例子(Clion IDE)[更新1:增加1.模版的应用,2.ma 的算法]
    一月5日
    一月5日
    一月5日
    一月5日
    一月5日
    一月5日
    一月5日
    一月5日
  • 原文地址:https://www.cnblogs.com/jiangfeilong/p/10224233.html
Copyright © 2011-2022 走看看