动态网站制作指南 [  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教程 ]的信息

本月文章推荐
.来自Apache的Java开源项目.
.控制对类内部数据或函数成员访问.
.Java开发学习过程中应该理解的一.
.J2ME MIDP 提供的最重要的图形元.
.使用AdminScripts脚本创建虚拟目.
.如何实时得到java object占用的空.
.用 JDOM 简化 XML 编程.
.关于EJB调用原理分析.
.共享有限的资源.
.Java 6中新型模态对话框API解析(.
.Jakarta Commons实现BeanCompara.
.jive中的abstractFactory.
.java版的MD5.
.基于JXTA的P2P应用开发.
.Java程序实现Logo画面的编程.
.Java Learning Path(三)过程篇.
.高效处理Java异常的两种方法.
.SQRT2 属性.
.从ifelse到设计模式的转变.
.JavaMail常见问题之POP3问题.

构建器内部的多形性方法的行为

发表日期:2008-1-5 |



  构建器调用的分级结构(顺序)为我们带来了一个有趣的问题,或者说让我们进入了一种进退两难的局面。若当前位于一个构建器的内部,同时调用预备构建的那个对象的一个动态绑定方法,那么会出现什么情况呢?在原始的方法内部,我们完全可以想象会发生什么——动态绑定的调用会在运行期间进行解析,因为对象不知道它到底从属于方法所在的那个类,还是从属于从它衍生出来的某些类。为保持一致性,大家也许会认为这应该在构建器内部发生。
  
  但实际情况并非完全如此。若调用构建器内部一个动态绑定的方法,会使用那个方法被覆盖的定义。然而,产生的效果可能并不如我们所愿,而且可能造成一些难于发现的程序错误。
  
  从概念上讲,构建器的职责是让对象实际进入存在状态。在任何构建器内部,整个对象可能只是得到部分组织——我们只知道基础类对象已得到初始化,但却不知道哪些类已经继续。然而,一个动态绑定的方法调用却会在分级结构里“向前”或者“向外”前进。它调用位于衍生类里的一个方法。假如在构建器内部做这件事情,那么对于调用的方法,它要操纵的成员可能尚未得到正确的初始化——这显然不是我们所希望的。
  
  通过观察下面这个例子,这个问题便会昭然若揭:
  
  //: PolyConstrUCtors.Java
  // Constructors and polymorphism
  // don't produce what you might eXPect.
  
  abstract class Glyph {
   abstract void draw();
   Glyph() {
    System.out.println("Glyph() before draw()");
    draw();
    System.out.println("Glyph() after draw()");
   }
  }
  
  class RoundGlyph extends Glyph {
   int radius = 1;
   RoundGlyph(int r) {
    radius = r;
    System.out.println(
     "RoundGlyph.RoundGlyph(), radius = "
     + radius);
   }
   void draw() {
    System.out.println(
     "RoundGlyph.draw(), radius = " + radius);
   }
  }
  
  public class PolyConstructors {
   public static void main(String[] args) {
    new RoundGlyph(5);
   }
  } ///:~
  
  在Glyph中,draw()方法是“抽象的”(abstract),所以它可以被其他方法覆盖。事实上,我们在RoundGlyph中不得不对其进行覆盖。但Glyph构建器会调用这个方法,而且调用会在RoundGlyph.draw()中止,这看起来似乎是有意的。但请看看输出结果:
  
  Glyph() before draw()
  RoundGlyph.draw(), radius = 0
  Glyph() after draw()
  RoundGlyph.RoundGlyph(), radius = 5
  
  当Glyph的构建器调用draw()时,radius的值甚至不是默认的初始值1,而是0。这可能是由于一个点号或者屏幕上根本什么都没有画而造成的。这样就不得不开始查找程序中的错误,试着找出程序不能工作的原因。
  
  前一节讲述的初始化顺序并不十分完整,而那是解决问题的要害所在。初始化的实际过程是这样的:
  
  (1) 在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零。
  
  (2) 就象前面叙述的那样,调用基础类构建器。此时,被覆盖的draw()方法会得到调用(的确是在RoundGlyph构建器调用之前),此时会发现radius的值为0,这是由于步骤(1)造成的。
  
  (3) 按照原先声明的顺序调用成员初始化代码。
  
  (4) 调用衍生类构建器的主体。
  
  采取这些操作要求有一个前提,那就是所有东西都至少要初始化成零(或者某些非凡数据类型与“零”等价的值),而不是仅仅留作垃圾。其中包括通过“合成”技术嵌入一个类内部的对象句柄。假如假若忘记初始化那个句柄,就会在运行期间出现违例事件。其他所有东西都会变成零,这在观看结果时通常是一个严重的警告信号。
  
  在另一方面,应对这个程序的结果提高警惕。从逻辑的角度说,我们似乎已进行了无懈可击的设计,所以它的错误行为令人非常不可思议。而且没有从编译器那里收到任何报错信息(C++在这种情况下会表现出更合理的行为)。象这样的错误会很轻易地被人忽略,而且要花很长的时间才能找出。
  
  因此,设计构建器时一个非凡有效的规则是:用尽可能简单的方法使对象进入就绪状态;假如可能,避免调用任何方法。在构建器内唯一能够安全调用的是在基础类中具有final属性的那些方法(也适用于private方法,它们自动具有final属性)。这些方法不能被覆盖,所以不会出现上述潜在的问题。
上一篇:为什么要用内部类:控制框架 人气:570
下一篇:产生正确的行为 人气:399
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-10-12 team论坛 v2.0.4 bulid 080916 A
2008-10-12 Roclog v3.1.6
2008-10-12 SupeV v1.0.1 简体中文 GBK
2008-10-12 NetCMS v1.6.0.1010 正式版
2008-10-12 PHP考试系统PPFrame v1.2.7
2008-10-12 LPAS个人相册 v1.6.3
2008-10-12 快问仿百度知道系统 动态-静态-互
2008-10-12 方卡广告防点击系统 V1.0 GB2312
2008-10-12 泡菜内容管理系统[PCMS] v1.0 Bu
2008-10-11 联系人分组工具 v1.1 中文破解版
2008-10-11 FaceMelter变脸 v2.0 汉化破解版
2008-10-11 PathTracker道路跟踪仪 v1.2 破解
2008-10-11 Rooms手机聊天室 v0.6.7 破解版
2008-10-11 RemoteDesktop远程桌面 v1.0 破解
2008-10-11 ProRemote远程调音台 v1.0.1 破解
2008-10-11 PicShare照片共享 v1.0.0 破解版
2008-10-11 Photogene照片编辑器 v1.5 汉化破
2008-10-11 WriteRoom共享文档 v1.0 破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | js/vbs加密 | md5加密 | 进制转换 | UTF-8 转换工具 | Html转换js | Html转换asp | Html转换php | Html转换perl
实用工具:汉字翻译拼音 | 拼音字典 | 符号对照表 | 个税计算 | 实时汇率查询换算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 | 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵
SEO対策 中国語教室 ホームページ作成