动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息



本月文章推荐
.getUTCDate 方法.
.企业级应用中开发 J2EE 应用的黄.
.用Java语言编写通过代理访问的应.
.菜鸟初学Java的备忘录(二).
.使用Java编写NT服务程序.
.Hibernate3发布beta版本 支持EJB.
.对于JAVA基础测试中常见的异常问.
.Java 12 大 特 色 介 绍.
.类装入问题解密,第 3 部分: 处理.
.初学Java注意什么.
.推荐两本iava书.
.手机与Servlet的网络通信技巧.
.配置WebLogic8.1和Hibernate3.0二.
.java工具包的安装,配置和使用.
.WebWork的强大的验证器.
.用J2SE 1.4进行Internet安全编程.
.Eclipse插件开发之EasyExplorer.
.JSF,为什么把简单的事情复杂化?.
.Log4j和JDBMonitor的比较.
.Java核心代码例程之:JavaMail--.

方法和作用域中的内部类

发表日期:2008-1-5 |



  至此,我们已基本理解了内部类的典型用途。对那些涉及内部类的代码,通常表达的都是“单纯”的内部类,非常简单,且极易理解。然而,内部类的设计非常全面,不可避免地会碰到它们的其他大量用法——假若我们在一个方法甚至一个任意的作用域内创建内部类。有两方面的原因促使我们这样做:
  
  (1) 正如前面展示的那样,我们预备实现某种形式的接口,使自己能创建和返回一个句柄。
  
  (2) 要解决一个复杂的问题,并希望创建一个类,用来辅助自己的程序方案。同时不愿意把它公开。
  
  在下面这个例子里,将修改前面的代码,以便使用:
  
  (1) 在一个方法内定义的类
  
  (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; }
    }
    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;
  
  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) {
    Parcel6 p = new Parcel6();
    Contents c = p.cont();
   }
  } ///:~
  
  cont()方法同时合并了返回值的创建代码,以及用于表示那个返回值的类。除此以外,这个类是匿名的——它没有名字。而且看起来似乎更让人摸不着头脑的是,我们预备创建一个Contents对象:
  
  return new Contents()
  
  但在这之后,在碰到分号之前,我们又说:“等一等,让我先在一个类定义里再耍一下花招”:
  
  return new Contents() {
  private int i = 11;
  public int value() { return i; }
  };
  
  这种希奇的语法要表达的意思是:“创建从Contents衍生出来的匿名类的一个对象”。由new表达式返回的句柄会自动上溯造型成一个Contents句柄。匿名内部类的语法其实要表达的是:
  
  class MyContents extends Contents {
  private int i = 11;
  public int value() { return i; }
  }
  return new MyContents();
  
  在匿名内部类中,Contents是用一个默认构建器创建的。下面这段代码展示了基础类需要含有自变量的一个构建器时做的事情:
  
  //: Parcel7.java
  // An anonymous inner class that calls the
  // base-class constrUCtor
  package c07.innerscopes;
  
  public class Parcel7 {
   public Wrapping wrap(int x) {
    // Base constructor call:
    return new Wrapping(x) {
     public int value() {
      return super.value() * 47;
     }
    }; // Semicolon required
   }
   public static void main(String[] args) {
    Parcel7 p = new Parcel7();
    Wrapping w = p.wrap(10);
   }
  } ///:~
  
  也就是说,我们将适当的自变量简单地传递给基础类构建器,在这儿表现为在“new Wrapping(x)”中传递x。匿名类不能拥有一个构建器,这和在调用super()时的常规做法不同。
  
  在前述的两个例子中,分号并不标志着类主体的结束(和C++不同)。相反,它标志着用于包含匿名类的那个表达式的结束。因此,它完全等价于在其他任何地方使用分号。
  
  若想对匿名内部类的一个对象进行某种形式的初始化,此时会出现什么情况呢?由于它是匿名的,没有名字赋给构建器,所以我们不能拥有一个构建器。然而,我们可在定义自己的字段时进行初始化:
  
  //: Parcel8.java
  // An anonymous inner class that performs
  // initialization. A briefer version
  // of Parcel5.java.
  package c07.innerscopes;
  
  public class Parcel8 {
   // Argument must be final to use inside
   // anonymous inner class:
   public Destination dest(final String dest) {
    return new Destination() {
     private String label = dest;
     public String readLabel() { return label; }
    };
   }
   public static void main(String[] args) {
    Parcel8 p = new Parcel8();
    Destination d = p.dest("Tanzania");
   }
  } ///:~
  
  若试图定义一个匿名内部类,并想使用在匿名内部类外部定义的一个对象,则编译器要求外部对象为final属性。这正是我们将dest()的自变量设为final的原因。假如忘记这样做,就会得到一条编译期出错提示。
  
  只要自己只是想分配一个字段,上述方法就肯定可行。但假如需要采取一些类似于构建器的行动,又应怎样操作呢?通过Java 1.1的实例初始化,我们可以有效地为一个匿名内部类创建一个构建器:
  
  //: Parcel9.java
  // Using "instance initialization" to perform
  // construction on an anonymous inner class
  package c07.innerscopes;
上一篇:引用外部类对象 人气:386
下一篇:链接到外部类 人气:298
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-24 Sablog-X v2.0 预览版
2008-7-24 帝国备份王EmpireBak 2008 正式版
2008-7-24 网趣网上购物系统时尚版 v8.2
2008-7-24 纵横B2B电子商务系统XYECS!B2B v
2008-7-24 e路小说小偷 v1.2.0723
2008-7-24 凌风美女图片站程序 v2.2
2008-7-24 TOM15电影收索程序
2008-7-24 清风信息自动采集生成系统 v1.0
2008-7-24 QQ邮箱编辑器 v1.0 (小小菜刀ASP
2008-7-19 UltraEdit 简体中文增强版 14.10
2008-7-19 CentOS 5.2 i386 LiveCD
2008-7-19 Snapture多功能相机 v1.4
2008-7-19 iAcces中文输入法 v1.0Build016
2008-7-19 Cookbook烹饪秘籍 v2.5
2008-7-19 苹果专用DVD转换工具 v1.1.59汉化
2008-7-19 Modem修复软件ZiPhone修改版04.0
2008-7-19 AgileMessenger即时通讯工具美化
2008-7-19 Sketches画图软件 v0.7b6破解版


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号