当前位置:七道奇文章资讯编程技术Java编程
日期:2011-03-22 16:17:00  来源:本站整理

构建器内部的多形性办法的行为[Java编程]

赞助商链接



  本文“构建器内部的多形性办法的行为[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
构建器调用的分级构造(次序)为我们带来了一个风趣的问题,大概说让我们进入了一种进退两难的局面.若当前位于一个构建器的内部,同时调用预备构建的那个对象的一个动态绑定办法,那么会呈现什么情形呢?在原始的办法内部,我们完好可以想象会发生什么——动态绑定的调用会在运行期间举行解析,因为对象不知道它到底从属于办法所在的那个类,还是从属于从它衍生出来的某些类.为保持一致性,大家大概会认为这应当在构建器内部发生.
但实际情形并非完好如此.若调用构建器内部一个动态绑定的办法,会利用那个办法被覆盖的定义.但是,产生的效果大概并不如我们所愿,并且大概造成一些难于发现的程序错误.
从概念上讲,构建器的职责是让对象实际进入存在状况.在任何构建器内部,整个对象大概只是得到部份组织——我们只知道底子类对象已得到初始化,但却不知道哪些类已经担当.但是,一个动态绑定的办法调用却会在分级构造里“向前”大概“向外”行进.它调用位于衍生类里的一个办法.假如在构建器内部做这件事情,那么关于调用的办法,它要操作的成员大概还没有得到精确的初始化——这明显不是我们所但愿的.
通过察看下面这个例子,这个问题便会昭然若揭:
//: 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属性).这些办法不能被覆盖,所以不会呈现上述潜在的问题.
  以上是“构建器内部的多形性办法的行为[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
  • 构建器内部的多形性办法的行为
  • 本文地址: 与您的QQ/BBS好友分享!
    • 好的评价 如果您觉得此文章好,就请您
        0%(0)
    • 差的评价 如果您觉得此文章差,就请您
        0%(0)

    文章评论评论内容只代表网友观点,与本站立场无关!

       评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
    Copyright © 2020-2022 www.xiamiku.com. All Rights Reserved .