友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第89章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




    //! Parcel3。PContents c = p。new PContents();  

  }  

} ///:~  

  

现在,Contents 和Destination 代表可由客户程序员使用的接口(记住接口会将自己的所有成员都变成 

public 属性)。为方便起见,它们置于单独一个文件里,但原始的 Contents 和Destination 在它们自己的 

文件中是相互public 的。  

在Parcel3 中,一些新东西已经加入:内部类PContents 被设为 private,所以除了Parcel3 之外,其他任 

何东西都不能访问它。PDestination 被设为 protected,所以除了 Parcel3,Parcel3 包内的类(因为 

protected 也为包赋予了访问权;也就是说,protected 也是“友好的”),以及Parcel3 的继承者之外,其 

他任何东西都不能访问 PDestination。这意味着客户程序员对这些成员的认识与访问将会受到限制。事实 

上,我们甚至不能下溯造型到一个 private 内部类(或者一个protected 内部类,除非自己本身便是一个继 

承者),因为我们不能访问名字,就象在 classTest 里看到的那样。所以,利用private 内部类,类设计人 

员可完全禁止其他人依赖类型编码,并可将具体的实施细节完全隐藏起来。除此以外,从客户程序员的角度 

来看,一个接口的范围没有意义的,因为他们不能访问不属于公共接口类的任何额外方法。这样一来,Java 

编译器也有机会生成效率更高的代码。  

普通(非内部)类不可设为private 或 protected——只允许 public 或者“友好的”。  

注意Contents 不必成为一个抽象类。在这儿也可以使用一个普通类,但这种设计最典型的起点依然是一个 

 “接口”。  



7。6。2  方法和作用域中的内部类  



至此,我们已基本理解了内部类的典型用途。对那些涉及内部类的代码,通常表达的都是“单纯”的内部 

类,非常简单,且极易理解。然而,内部类的设计非常全面,不可避免地会遇到它们的其他大量用法——假 

若我们在一个方法甚至一个任意的作用域内创建内部类。有两方面的原因促使我们这样做:  

(1) 正如前面展示的那样,我们准备实现某种形式的接口,使自己能创建和返回一个句柄。  

(2) 要解决一个复杂的问题,并希望创建一个类,用来辅助自己的程序方案。同时不愿意把它公开。  

  

在下面这个例子里,将修改前面的代码,以便使用:  

(1) 在一个方法内定义的类  



                                                                                       181 


…………………………………………………………Page 183……………………………………………………………

(2) 在方法的一个作用域内定义的类  

(3) 一个匿名类,用于实现一个接口  

(4) 一个匿名类,用于扩展拥有非默认构建器的一个类  

(5) 一个匿名类,用于执行字段初始化  

(6) 一个匿名类,通过实例初始化进行构建(匿名内部类不可拥有构建器)  

  

所有这些都在 innerscopes 包内发生。首先,来自前述代码的通用接口会在它们自己的文件里获得定义,使 

它们能在所有的例子里使用:  

  

//: Destination。java  

package c07。innerscopes;  

  

interface Destination {  

  String readLabel();  

} ///:~  

  

由于我们已认为Contents 可能是一个抽象类,所以可采取下面这种更自然的形式,就象一个接口那样:  

  

//: Contents。java  

package c07。innerscopes;  

  

interface Contents {  

  int value();  

} ///:~  

  

尽管是含有具体实施细节的一个普通类,但Wrapping 也作为它所有衍生类的一个通用“接口”使用:  

  

//: Wrapping。java  

package c07。innerscopes;  

  

public class Wrapping {  

  private int i;  

  public Wrapping(int x) { i = x; }  

  public int value() { return i; }  

} ///:~  

  

在上面的代码中,我们注意到 Wrapping 有一个要求使用自变量的构建器,这就使情况变得更加有趣了。  

第一个例子展示了如何在一个方法的作用域(而不是另一个类的作用域)中创建一个完整的类:  

  

//: Parcel4。java  

// Nesting a class within a method  

package c07。innerscopes;  

  

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; }  



                                                                                          182 


…………………………………………………………Page 184……………………………………………………………

    }  

    return new PDestination(s);  

  }  

  public static void main(String'' args) {  

    Parcel4 p = new Parcel4();  

    Destination d = p。dest(〃Tanzania〃);  

  }  

} ///:~  

  

PDestination 类属于 dest()的一部分,而不是 Parcel4 的一部分(同时注意可为相同目录内每个类内部的一 

个内部类使用类标识符 PDestination,这样做不会发生命名的冲突)。因此,PDestination 不可从 dest() 

的外部访问。请注意在返回语句中发生的上溯造型——除了指向基础类Destination 的一个句柄之外,没有 

任何东西超出dest()的边界之外。当然,不能由于类PDestination 的名字置于 dest()内部,就认为在 

dest()返回之后 PDestination 不是一个有效的对象。  

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

  

//: Parcel5。java  

// Nesting a class within a scope  

package c07。innerscopes;  

  

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语句的作用域内。这并不意味着类是有条件创建的——它会随同其他所有东 

西得到编译。然而,在定义它的那个作用域之外,它是不可使用的。除这些以外,它看起来和一个普通类并 

没有什么区别。  

下面这个例子看起来有些奇怪:  

  

//: Parcel6。java  

// A method that returns an anonymous inner class  

package c07。innerscopes;  

  



                                                                                          183 


…………………………………………………………Page 185……………………………………………………………

public class Parcel6 {  

  public Contents cont() {  

    return new Contents() {  

      private int i = 11;  

      public int value() { return i; }  

    }; // Semicolon required in this case  

  }  

  public static void main(String'' args) {  

  
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!