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

📄 chap07.htm

📁 java书籍《thinking in java》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A constructor for the base class is
always called in the constructor for a derived class, chaining up the
inheritance hierarchy so that a constructor for every base class is called. This
makes sense because the constructor has a special job: to see that the object is
built properly. A derived class has access to its own members only, and not to
those of the base class (whose members are typically <B>private</B>). Only the
base-class constructor has the proper knowledge and access to initialize its own
elements. Therefore, it&#8217;s essential that all constructors get called,
otherwise the entire object wouldn&#8217;t be constructed. That&#8217;s why the
compiler enforces a constructor call for every portion of a derived class. It
will silently call the default constructor if you don&#8217;t explicitly call a
base-class constructor in the derived-class constructor body. If there is no
default constructor, the compiler will complain. (In the case where a class has
no constructors, the compiler will automatically synthesize a default
constructor.) 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I39' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I40>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Let&#8217;s take a look at an example
that shows the effects of composition, inheritance, and polymorphism on the
order of construction:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:Sandwich.java</font>
<font color=#009900>// Order of constructor calls.</font>

<font color=#0000ff>class</font> Meal {
  Meal() { System.out.println(<font color=#004488>"Meal()"</font>); }
}

<font color=#0000ff>class</font> Bread {
  Bread() { System.out.println(<font color=#004488>"Bread()"</font>); }
}

<font color=#0000ff>class</font> Cheese {
  Cheese() { System.out.println(<font color=#004488>"Cheese()"</font>); }
}

<font color=#0000ff>class</font> Lettuce {
  Lettuce() { System.out.println(<font color=#004488>"Lettuce()"</font>); }
}

<font color=#0000ff>class</font> Lunch <font color=#0000ff>extends</font> Meal {
  Lunch() { System.out.println(<font color=#004488>"Lunch()"</font>);}
}

<font color=#0000ff>class</font> PortableLunch <font color=#0000ff>extends</font> Lunch {
  PortableLunch() {
    System.out.println(<font color=#004488>"PortableLunch()"</font>);
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Sandwich <font color=#0000ff>extends</font> PortableLunch {
  Bread b = <font color=#0000ff>new</font> Bread();
  Cheese c = <font color=#0000ff>new</font> Cheese();
  Lettuce l = <font color=#0000ff>new</font> Lettuce();
  Sandwich() { 
    System.out.println(<font color=#004488>"Sandwich()"</font>);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    <font color=#0000ff>new</font> Sandwich();
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This example creates a complex class out
of other classes, and each class has a constructor that announces itself. The
important class is <B>Sandwich</B>, which reflects three levels of inheritance
(four, if you count the implicit inheritance from <B>Object</B>) and three
member objects. When a <B>Sandwich</B> object is created in <B>main(&#160;)</B>,
the output is:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This means that the order of constructor
calls for a complex object is as follows:
<A NAME="Index709"></A><A NAME="Index710"></A><A NAME="Index711"></A><A NAME="Index712"></A>

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I40' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I41>
</FONT><BR></P></DIV>
<OL>
<LI><FONT FACE="Verdana">	</FONT><FONT FACE="Georgia">The base-class constructor
is called. This step is repeated recursively such that the root of the hierarchy
is constructed first, followed by the next-derived class, etc., until the
most-derived class is reached.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I41' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I42>
</FONT><LI><FONT FACE="Verdana">	</FONT><FONT FACE="Georgia">Member
initializers are called in the order of declaration.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I42' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I43>
</FONT><LI><FONT FACE="Verdana">	</FONT><FONT FACE="Georgia">The
body of the derived-class constructor is called.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I43' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I44>
</FONT></OL><DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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&#8217;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&#8217;re in the derived-class constructor, all the members you can
access in the base class have been initialized. &#8220;Knowing that all members
are valid&#8221; 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 example above). 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&#8217;t handle every case, as you will see in the next section.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I44' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I45>
</FONT><A NAME="_Toc481064635"></A><BR></P></DIV>
<A NAME="Heading245"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Inheritance and finalize(&#160;)</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When you use composition to create a new
class, you never worry about finalizing the member objects of that class. Each
member is an independent object, and thus is <A NAME="Index713"></A>garbage
collected and finalized regardless of whether it happens to be a member of your
class. With inheritance, however, you must override
<A NAME="Index714"></A><A NAME="Index715"></A><B>finalize(&#160;)</B> in the
derived class if you have any special cleanup that must happen as part of
garbage collection. When you override <B>finalize(&#160;)</B> in an inherited
class, it&#8217;s important to remember to call the base-class version of
<B>finalize(&#160;)</B>, since otherwise the base-class finalization will not
happen. The following example proves this:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:Frog.java</font>
<font color=#009900>// Testing finalize with inheritance.</font>

<font color=#0000ff>class</font> DoBaseFinalization {
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>boolean</font> flag = <font color=#0000ff>false</font>;
}

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

<font color=#0000ff>class</font> LivingCreature {
  Characteristic p = 
    <font color=#0000ff>new</font> Characteristic(<font color=#004488>"is alive"</font>);
  LivingCreature() {
    System.out.println(<font color=#004488>"LivingCreature()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> finalize() <font color=#0000ff>throws</font> Throwable {
    System.out.println(
      <font color=#004488>"LivingCreature finalize"</font>);
    <font color=#009900>// Call base-class version LAST!</font>
    <font color=#0000ff>if</font>(DoBaseFinalization.flag)
      <font color=#0000ff>super</font>.finalize();
  }
}

<font color=#0000ff>class</font> Animal <font color=#0000ff>extends</font> LivingCreature {
  Characteristic p = 
    <font color=#0000ff>new</font> Characteristic(<font color=#004488>"has heart"</font>);
  Animal() {
    System.out.println(<font color=#004488>"Animal()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> finalize() <font color=#0000ff>throws</font> Throwable {
    System.out.println(<font color=#004488>"Animal finalize"</font>);
    <font color=#0000ff>if</font>(DoBaseFinalization.flag)
      <font color=#0000ff>super</font>.finalize();
  }
}

<font color=#0000ff>class</font> Amphibian <font color=#0000ff>extends</font> Animal {
  Characteristic p = 
    <font color=#0000ff>new</font> Characteristic(<font color=#004488>"can live in water"</font>);
  Amphibian() {
    System.out.println(<font color=#004488>"Amphibian()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> finalize() <font color=#0000ff>throws</font> Throwable {
    System.out.println(<font color=#004488>"Amphibian finalize"</font>);
    <font color=#0000ff>if</font>(DoBaseFinalization.flag)
      <font color=#0000ff>super</font>.finalize();
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Frog <font color=#0000ff>extends</font> Amphibian {
  Frog() {
    System.out.println(<font color=#004488>"Frog()"</font>);
  }
  <font color=#0000ff>protected</font> <font color=#0000ff>void</font> finalize() <font color=#0000ff>throws</font> Throwable {
    System.out.println(<font color=#004488>"Frog finalize"</font>);
    <font color=#0000ff>if</font>(DoBaseFinalization.flag)
      <font color=#0000ff>super</font>.finalize();
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    <font color=#0000ff>if</font>(args.length != 0 &amp;&amp; 
       args[0].equals(<font color=#004488>"finalize"</font>))
       DoBaseFinalization.flag = <font color=#0000ff>true</font>;
    <font color=#0000ff>else</font>
      System.out.println(<font color=#004488>"Not finalizing bases"</font>);
    <font color=#0000ff>new</font> Frog(); <font color=#009900>// Instantly becomes garbage</font>
    System.out.println(<font color=#004488>"Bye!"</font>);
    <font color=#009900>// Force finalizers to be called:</font>
    System.gc();
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The class <B>DoBaseFinalization</B>
simply holds a flag that indicates to each class in the hierarchy whether to
call
<A NAME="Index716"></A><A NAME="Index717"></A><B>super.finalize(&#160;)</B>.
This flag is set based on a command-line argument, so you can view the behavior
with and without base-class finalization.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER7_I45' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER7_I46>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Each class in the hierarchy also contains
a member object of class <B>Characteristic</B>. You will see that regardles

⌨️ 快捷键说明

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