在方法和作用域内的内部类

目前为止,你所看到的只是内部类典型的用途。通常,如果你要读写的代码包含了内部类,
那么它们都是“平凡的”内部类,简单并且容易理解。然而,内部类的设计却是相当完备
的。如果你选择使用内部类,它还有许多难以理解的使用方式。例如,可以在一个方法里
面或者在任意的作用域内定义内部类。这么做有两个理由:


1. 如前所示,你实现了某类型的接口,于是可以创建并返回对其的引用。
2. 你要解决一个复杂的问题,想创建一个类来辅助你的解决方案,但是又不希望
这个类是公共可用的。


在后面的例子中,先前的代码将被修改以用来实现:


1. 一个定义在方法中的类
2. 一个定义在作用域内的类,此作用域在方法的内部
3. 一个实现了接口的匿名类
4. 一个匿名类,扩展了有非缺省构造器的类
5. 一个匿名类,执行成员初始化
6. 一个匿名类,通过实例初始化实现构造(匿名类不可能有构造器)


虽然 Wrapping 只是一个普通的类,但同时也被其导出类作为通用“接口”使用。


//: c08:Wrapping.java
public class Wrapping { 
private int i;
public Wrapping(int x) { i = x; } 
public int value() { return i; } 
} ///:~


请注意 Wrapping 的构造器,它需要一个参数,这使得事情更有趣了。
 






第一个例子展示了在方法的作用域内(而不是在其它类的作用域内)创建一个完整的类。
这被称作局部内部类(local inner class):


//: c08:Parcel4.java
// Nesting a class within a method.


public class Parcel4 {
public Destination dest(String s) { 
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
        label = whereTo; 
      }
public String readLabel() { return label; } 
    }
return new PDestination(s); 
  }
public static void main(String[] args) { 
    Parcel4 p = new Parcel4(); 
    Destination d = p.dest("Tanzania");
  }
} ///:~


与其说 PDestination 类是 Parcel4 的一部分,不如说是 dest()方法的一部分。(要注意
到,你可以在同一个子目录下的任意类中定义名为 PDestination 的内部类,这并不会有命
名冲突。)所以,在 dest()之外不能访问 PDestination。注意出现在 return 语句中的向
上转型——返回的是 Destination 的引用,它是 PDestination 的基类。当然,在 dest()
中定义了内部类 PDestination,并不意味着一旦 dest()方法执行完毕,PDestination 就
不可用了。


下一个例子展示了如何在任意的作用域内嵌入一个内部类:


//: c08:Parcel5.java
// Nesting a class within a scope.


public class Parcel5 {
private void internalTracking(boolean b) { 
if(b) { 
class TrackingSlip {
private String id;
        TrackingSlip(String s) {
          id = s;
        }
        String getSlip() { return id; }
      }
      TrackingSlip ts = new TrackingSlip("slip"); 
      String s = ts.getSlip(); 
    }
// Can't use it here! Out of scope:
//! TrackingSlip ts = new TrackingSlip("x");
  }
public void track() { internalTracking(true); } 
public static void main(String[] args) { 
    Parcel5 p = new Parcel5(); 
    p.track();
  }
} ///:~


TrackingSlip 类被嵌入在 if 语句的作用域内,这并不是说它的创建是有条件的,它其实与
别的类一样都经过编译了。然而,在定义 TrackingSlip 的作用域之外,它是不可用的。除

此之外,它与普通的类一样。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值