首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

第10章-内部类_匿名内部类

2013-08-04 
第10章--内部类_匿名内部类public interface Contents{int value()} public class Parcel7{public Conten

第10章--内部类_匿名内部类
public interface Contents{ int value();} public class Parcel7{ public Contents contents() { //借助于Contents接口,创建一个匿名内部类的唯一实例 //该实例必须要 实现 借助的 接口Contents return new Contents() { private int i = 11; public int value() { TT(); return i; } //改方法只能在匿名内部类内部使用 public void TT() { } }; //这个分号不能少 } public static void main(String[] args) { Parcel7 p = new Parcel7(); Contents c = p.contents(); }}

?2. 借助于 常规类的 构造函数 生成匿名内部类的唯一对象

? ?这种方式生成的内部类,其实相当于把协助生成匿名内部类唯一对象的

? ?那个常规类当成一个接口来使用(可以使用常规类的public方法),同时生成的匿名内部类唯一实例可以使用

? ?那个常规类的protected方法以及friend方法(方法前面什么都不加).

? ?但是匿名内部类自己内部新增的public方法 不能被使用,所以这中方式 与继承也不用.

? ?介于 实现接口和继承之间.

? ?

? ?//协助生成内部类唯一对象的 常规类?

?

public class Wrapping{  private int i;  public Wrapping(int x)  {    i = x;  }  public int value()  {    return i;  }    //protected方法  protected void testProtected()  {    System.out.println("testProtected()");  }    //friend 方法   void testFriend()  {    System.out.println("testFriend()");  }      static void  testStatic()   {     System.out.println("testStatic()");   }}

?当做返回值的匿名内部类.

public class Parcel8{  public Wrapping wrapping(int x)  {    // 通过借助常规类的构造函数方法实现的匿名内部类,介于继承和实现接口之间:    return new Wrapping(x)     //匿名内部类 的对象 要么作为 方法返回值; 要么作为方法的参数;    //这样 匿名内部类 总是作为一个已知的类的子类 或者 已知接口的实现类(这里 都涉及到向上转型)    //所以 创建匿名内部类 的语法 总是 new 基类() {类定义}  或 new 接口() {类定义}    //匿名内部类 不可能有构造器(因为匿名内部类没有名字)  所以匿名内部类只能使用 默认构造器来创建对象    { // Pass constructor argument.      public int value()      {        return super.value() * 47;      }    }; // Semicolon required  }  public static void main(String[] args)  {    Parcel8 p = new Parcel8();    Wrapping w = p.wrapping(10);    w.testFriend(); //什么都不加的方法    w.testProtected(); //protected方法    w.testStatic(); //静态方法  }} /*** 这里必须要传递一个参数x给构造函数的原因* 1. 如果 类一个参数构造器都没有,则编译器会自动加一个默认构造器(即无参构造器)* 2. 假如 类 已经有一个构造器,则编译器不会再自动加上默认构造器* 3. 导出类的构造器必须首先要调用基类的构造器,*    如果基类没有默认构造器(比如 上面的Wrapping 只有一个构造器Wrapping(int x)),*    则导出类的构造器必须首先要显式的调用基类的构造器,因此上面内部类定义时必须传入参数x给*    基类的构造器Wrapping(int x)*  *  总之,如果导出类的构造器没有首先显式的调用基类的构造器,则编译器会自动让导出类调用基类的默认*  构造器,如果基类没有默认构造器,则导出类必须首先显式的调用基类的其他构造器,否则编译不通过.*/

?3. 匿名内部类中直接使用了外部的对象,比如定义匿名内部类的函数的参数,那么这个参数必须是final的.

public class Parcel9{  private int iTmp = 3;    public Destination destination(final String dest)  {    return new Destination()    {      private String label = dest;       //局部内部类直接使用了 函数的参数,则参数必须为final的.      public int iTmpInner = iTmp;       //局部内部类使用 外围类 字段 iTmp, iTmp 不 需要 是final的(内部类中自动拥有外围类的引用)            public String readLabel()      {        iTmpInner++;        return label;      }    };  }  public static void main(String[] args)  {    Parcel9 p = new Parcel9();    Destination d = p.destination("Tasmania");  }} 

?4. 匿名内部类没有构造函数,可以使用初始化块完成初始化.

?

? ?下面的例子中,传递给匿名内部类的参数i 不需要 是final的,因为i没有直接在匿名内部类中使用,

? ?而是传递给匿名内部类的基类使用.

abstract class Base{  public Base(int i)  {    System.out.println("Base constructor, i = " + i);  }  public abstract void f();}public class AnonymousConstructor{  public static Base getBase(int i)  {    return new Base(i)     //参数i 不需要 是final的,因为i没有直接在匿名内部类中使用,    //而是传递给匿名内部类的基类使用.    {      private int cost;      {        cost = 100;//匿名内部类, 初始化块中的初始化,        System.out.println("Inside instance initializer");      }      public void f()      {        System.out.println("In anonymous f()");      }            public void g()       //匿名内部类,继承了基类,即使自己新增了一个方法g(),返回的唯一的匿名内部类的对象也无法使用这个新增的方法      //所以,匿名内部类的继承 其实 相当于实现接口      {        System.out.println("In anonymous g()");      }    };  }  public static void main(String[] args)  {    Base base = getBase(47);    base.f();  }}

?

热点排行