⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij309.htm

📁 这也是我们java老师给我们的thinking in java的一些资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1062" title="Send BackTalk
Comment">Feedback</a></font></li></ol><p>The order of the constructor calls is important. When you inherit, you know all about the base class and can access any <b>public</b> and <b>protected</b> members of the base class. This means that you must be able to assume that all the members of the base class are valid when you&#146;re in the derived class. In a normal method, construction has already taken place, so all the members of all parts of the object have been built. Inside the constructor, however, you must be able to assume that all members that you use have been built. The only way to guarantee this is for the base-class constructor to be called first. Then when you&#146;re in the derived-class constructor, all the members you can access in the base class have been initialized. Knowing that all members are valid inside the constructor is also the reason that, whenever possible, you should initialize all member objects (that is, objects placed in the class using composition) at their point of definition in the class (e.g., <b>b</b>, <b>c,</b> and <b>l</b> in the preceding example). If you follow this practice, you will help ensure that all base class members <i>and</i> member objects of the current object have been initialized. Unfortunately, this doesn&#146;t handle every case, as you will see in the next section. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1063" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc24775666"></a><a name="Heading6501"></a>Inheritance and
cleanup</h3>
<p>When using composition and inheritance to create a new class, most of the time you won&#146;t have to worry about cleaning up; subobjects can usually be left to the garbage collector. If you do have cleanup issues, you must be diligent and create a <b>dispose(&#160;) </b>method (the name I have chosen to use here; you may come up with something better) for your new class. And with inheritance, you must override <a name="Index657"></a><a name="Index658"></a><b>dispose(&#160;)</b> in the derived class if you have any special cleanup that must happen as part of garbage collection. When you override <b>dispose(&#160;)</b> in an inherited class, it&#146;s important to remember to call the base-class version of <b>dispose(&#160;)</b>, since otherwise the base-class cleanup will not happen. The following example demonstrates this:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:Frog.java</font>
<font color=#009900>// Cleanup and inheritance.</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;

<font color=#0000ff>class</font> Characteristic {
  <font color=#0000ff>private</font> String s;
  Characteristic(String s) {
    <font color=#0000ff>this</font>.s = s;
    System.out.println(<font color=#004488>"Creating Characteristic "</font> + s);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> dispose() {
    System.out.println(<font color=#004488>"finalizing Characteristic "</font> + s);
  }
}

<font color=#0000ff>class</font> Description {
  <font color=#0000ff>private</font> String s;
  Description(String s) {
    <font color=#0000ff>this</font>.s = s;
    System.out.println(<font color=#004488>"Creating Description "</font> + s);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> dispose() {
    System.out.println(<font color=#004488>"finalizing Description "</font> + s);
  }
}

<font color=#0000ff>class</font> LivingCreature {
  <font color=#0000ff>private</font> Characteristic p = <font color=#0000ff>new</font> Characteristic(<font color=#004488>"is alive"</font>);
  <font color=#0000ff>private</font> Description t =
    <font color=#0000ff>new</font> Description(<font color=#004488>"Basic Living Creature"</font>);
  LivingCreature() {
    System.out.println(<font color=#004488>"LivingCreature()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> dispose() {
    System.out.println(<font color=#004488>"LivingCreature dispose"</font>);
    t.dispose();
    p.dispose();
  }
}

<font color=#0000ff>class</font> Animal <font color=#0000ff>extends</font> LivingCreature {
  <font color=#0000ff>private</font> Characteristic p= <font color=#0000ff>new</font> Characteristic(<font color=#004488>"has heart"</font>);
  <font color=#0000ff>private</font> Description t =
    <font color=#0000ff>new</font> Description(<font color=#004488>"Animal not Vegetable"</font>);
  Animal() {
    System.out.println(<font color=#004488>"Animal()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> dispose() {
    System.out.println(<font color=#004488>"Animal dispose"</font>);
    t.dispose();
    p.dispose();
    <font color=#0000ff>super</font>.dispose();
  }
}

<font color=#0000ff>class</font> Amphibian <font color=#0000ff>extends</font> Animal {
  <font color=#0000ff>private</font> Characteristic p =
    <font color=#0000ff>new</font> Characteristic(<font color=#004488>"can live in water"</font>);
  <font color=#0000ff>private</font> Description t =
    <font color=#0000ff>new</font> Description(<font color=#004488>"Both water and land"</font>);
  Amphibian() {
    System.out.println(<font color=#004488>"Amphibian()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> dispose() {
    System.out.println(<font color=#004488>"Amphibian dispose"</font>);
    t.dispose();
    p.dispose();
    <font color=#0000ff>super</font>.dispose();
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Frog <font color=#0000ff>extends</font> Amphibian {
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
  <font color=#0000ff>private</font> Characteristic p = <font color=#0000ff>new</font> Characteristic(<font color=#004488>"Croaks"</font>);
  <font color=#0000ff>private</font> Description t = <font color=#0000ff>new</font> Description(<font color=#004488>"Eats Bugs"</font>);
  <font color=#0000ff>public</font> Frog() {
    System.out.println(<font color=#004488>"Frog()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> dispose() {
    System.out.println(<font color=#004488>"Frog dispose"</font>);
    t.dispose();
    p.dispose();
    <font color=#0000ff>super</font>.dispose();
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Frog frog = <font color=#0000ff>new</font> Frog();
    System.out.println(<font color=#004488>"Bye!"</font>);
    frog.dispose();
    monitor.expect(<font color=#0000ff>new</font> String[] {
      <font color=#004488>"Creating Characteristic is alive"</font>,
      <font color=#004488>"Creating Description Basic Living Creature"</font>,
      <font color=#004488>"LivingCreature()"</font>,
      <font color=#004488>"Creating Characteristic has heart"</font>,
      <font color=#004488>"Creating Description Animal not Vegetable"</font>,
      <font color=#004488>"Animal()"</font>,
      <font color=#004488>"Creating Characteristic can live in water"</font>,
      <font color=#004488>"Creating Description Both water and land"</font>,
      <font color=#004488>"Amphibian()"</font>,
      <font color=#004488>"Creating Characteristic Croaks"</font>,
      <font color=#004488>"Creating Description Eats Bugs"</font>,
      <font color=#004488>"Frog()"</font>,
      <font color=#004488>"Bye!"</font>,
      <font color=#004488>"Frog dispose"</font>,
      <font color=#004488>"finalizing Description Eats Bugs"</font>,
      <font color=#004488>"finalizing Characteristic Croaks"</font>,
      <font color=#004488>"Amphibian dispose"</font>,
      <font color=#004488>"finalizing Description Both water and land"</font>,
      <font color=#004488>"finalizing Characteristic can live in water"</font>,
      <font color=#004488>"Animal dispose"</font>,
      <font color=#004488>"finalizing Description Animal not Vegetable"</font>,
      <font color=#004488>"finalizing Characteristic has heart"</font>,
      <font color=#004488>"LivingCreature dispose"</font>,
      <font color=#004488>"finalizing Description Basic Living Creature"</font>,
      <font color=#004488>"finalizing Characteristic is alive"</font>
    });
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>Each class in the hierarchy also contains a member objects of types <b>Characteristic</b> and <b>Description</b>, which must also be disposed. The order of disposal should be the reverse of the order of initialization, in case one subobject is dependent on another. For fields, this means the reverse of the order of declaration (since fields are initialized in declaration order). For base classes (following the form that&#146;s used in C++ for destructors), you should perform the derived-class cleanup first, then the base-class cleanup. That&#146;s because the derived-class cleanup could call some methods in the base class that require the base-class components to be alive, so you must not destroy them prematurely. From the output you can see that all parts of the <b>Frog </b>object are disposed in reverse order of creation. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1067" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>From this example, you can see that although you don&#146;t always need to perform cleanup, when you do, the process requires care and awareness. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0468" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc312374057"></a><a name="_Toc375545340"></a><a name="_Toc24775667"></a><a name="Heading6623"></a>Behavior
of polymorphic methods <br>inside constructors<br></h3>
<p><a name="Index659"></a><a name="Index660"></a><a name="Index661"></a>The hierarchy of constructor calls brings up an interesting dilemma. What happens if you&#146;re inside a constructor and you call a dynamically-bound method of the object being constructed? Inside an ordinary method, you can imagine what will happen: The dynamically-bound call is resolved at run time, because the object cannot know whether it belongs to the class that the method is in or some class derived from it. For consistency, you might think this is what should happen inside constructors. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1068" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>This is not exactly the case. If you call a dynamically-bound method inside a constructor, the overridden definition for that method is used. However, the <i>effect</i> can be rather unexpected and can conceal some difficult-to-find bugs. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1069" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Conceptually, the constructor&#146;s job is to bring the object into existence (which is hardly an ordinary feat). Inside any constructor, the entire object might be only partially formed&#151;you can know only that the base-class objects have been initialized, but you cannot know which classes are inherited from you. A dynamically bound method call, however, reaches &#147;outward&#148; into the inheritance hierarchy. It calls a method in a derived class. If you do this inside a constructor, you call a method that might manipulate members that haven&#146;t been initialized yet&#151;a sure recipe for disaster. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1070" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>You can see the problem in the following example:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:PolyConstructors.java</font>
<font color=#009900>// Constructors and polymorphism</font>
<font color=#009900>// don't produce what you might expect.</font>
<font color=#000

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -