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

📄 chap06.htm

📁 java书籍《thinking in java》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c06:Bath.java</font>
<font color=#009900>// Constructor initialization with composition.</font>

<font color=#0000ff>class</font> Soap {
  <font color=#0000ff>private</font> String s;
  Soap() {
    System.out.println(<font color=#004488>"Soap()"</font>);
    s = <font color=#0000ff>new</font> String(<font color=#004488>"Constructed"</font>);
  }
  <font color=#0000ff>public</font> String toString() { <font color=#0000ff>return</font> s; }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Bath {
  <font color=#0000ff>private</font> String 
    <font color=#009900>// Initializing at point of definition:</font>
    s1 = <font color=#0000ff>new</font> String(<font color=#004488>"Happy"</font>), 
    s2 = <font color=#004488>"Happy"</font>, 
    s3, s4;
  Soap castille;
  <font color=#0000ff>int</font> i;
  <font color=#0000ff>float</font> toy;
  Bath() {
    System.out.println(<font color=#004488>"Inside Bath()"</font>);
    s3 = <font color=#0000ff>new</font> String(<font color=#004488>"Joy"</font>);
    i = 47;
    toy = 3.14f;
    castille = <font color=#0000ff>new</font> Soap();
  }
  <font color=#0000ff>void</font> print() {
    <font color=#009900>// Delayed initialization:</font>
    <font color=#0000ff>if</font>(s4 == <font color=#0000ff>null</font>)
      s4 = <font color=#0000ff>new</font> String(<font color=#004488>"Joy"</font>);
    System.out.println(<font color=#004488>"s1 = "</font> + s1);
    System.out.println(<font color=#004488>"s2 = "</font> + s2);
    System.out.println(<font color=#004488>"s3 = "</font> + s3);
    System.out.println(<font color=#004488>"s4 = "</font> + s4);
    System.out.println(<font color=#004488>"i = "</font> + i);
    System.out.println(<font color=#004488>"toy = "</font> + toy);
    System.out.println(<font color=#004488>"castille = "</font> + castille);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Bath b = <font color=#0000ff>new</font> Bath();
    b.print();
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that in the <B>Bath </B>constructor
a statement is executed before any of the initializations take place. When you
don&#8217;t initialize at the point of definition, there&#8217;s still no
guarantee that you&#8217;ll perform any initialization before you send a message
to an object reference&#8212;except for the inevitable run-time exception.

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

<backtalk:display ID=TIJ3_CHAPTER6_I12>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s the output for the
program:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Inside Bath()
Soap()
s1 = Happy
s2 = Happy
s3 = Joy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When <B>print(&#160;)</B> is called it
fills in <B>s4</B> so that all the fields are properly initialized by the time
they are used.

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

<backtalk:display ID=TIJ3_CHAPTER6_I13>
</FONT><A NAME="_Toc305593252"></A><A NAME="_Toc305628724"></A><A NAME="_Toc312374015"></A><A NAME="_Toc375545307"></A><A NAME="_Toc481064605"></A><BR></P></DIV>
<A NAME="Heading208"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Inheritance syntax<BR><A NAME="Index553"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Inheritance is an integral part of Java
(and OOP languages in general). It turns out that you&#8217;re always doing
inheritance when you create a class, because unless you explicitly inherit from
some other class, you implicitly inherit from Java&#8217;s
<A NAME="Index554"></A>standard root class <B>Object</B>.

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

<backtalk:display ID=TIJ3_CHAPTER6_I14>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The syntax for composition is obvious,
but to perform inheritance there&#8217;s a distinctly different form. When you
inherit, you say &#8220;This new class is like that old class.&#8221; You state
this in code by giving the name of the class as usual, but before the opening
brace of the class body, put the <A NAME="Index555"></A>keyword <B>extends</B>
followed by the name of the
<A NAME="Index556"></A><A NAME="Index557"></A><I>base class</I>. When you do
this, you automatically get all the data members and methods in the base class.
Here&#8217;s an example: 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I14' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER6_I15>
</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c06:Detergent.java</font>
<font color=#009900>// Inheritance syntax &amp; properties.</font>

<font color=#0000ff>class</font> Cleanser {
  <font color=#0000ff>private</font> String s = <font color=#0000ff>new</font> String(<font color=#004488>"Cleanser"</font>);
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> append(String a) { s += a; }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> dilute() { append(<font color=#004488>" dilute()"</font>); }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> apply() { append(<font color=#004488>" apply()"</font>); }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> scrub() { append(<font color=#004488>" scrub()"</font>); }
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> print() { System.out.println(s); }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Cleanser x = <font color=#0000ff>new</font> Cleanser();
    x.dilute(); x.apply(); x.scrub();
    x.print();
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Detergent <font color=#0000ff>extends</font> Cleanser {
  <font color=#009900>// Change a method:</font>
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> scrub() {
    append(<font color=#004488>" Detergent.scrub()"</font>);
    <font color=#0000ff>super</font>.scrub(); <font color=#009900>// Call base-class version</font>
  }
  <font color=#009900>// Add methods to the interface:</font>
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> foam() { append(<font color=#004488>" foam()"</font>); }
  <font color=#009900>// Test the new class:</font>
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Detergent x = <font color=#0000ff>new</font> Detergent();
    x.dilute();
    x.apply();
    x.scrub();
    x.foam();
    x.print();
    System.out.println(<font color=#004488>"Testing base class:"</font>);
    Cleanser.main(args);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This demonstrates a number of features.
First, in the <B>Cleanser</B> <B>append(&#160;)</B> method, <B>String</B>s are
concatenated to <B>s</B> using the <B>+=</B> operator, which is one of the
operators (along with &#8216;<B>+</B>&#8217;) that the Java designers
&#8220;overloaded&#8221; to work with
<A NAME="Index558"></A><A NAME="Index559"></A><A NAME="Index560"></A><B>String</B>s.

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

<backtalk:display ID=TIJ3_CHAPTER6_I16>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Second, both <B>Cleanser</B> and
<B>Detergent</B> contain a <A NAME="Index561"></A><B>main(&#160;)</B> method.
You can create a <B>main(&#160;)</B> for each one of your classes, and
it&#8217;s often recommended to code this way so that your test code is wrapped
in with the class. Even if you have a lot of classes in a program, only the
<B>main(&#160;)</B> for the class invoked on the command line will be called.
(As long as <B>main(&#160;)</B> is <B>public</B>, it doesn&#8217;t matter
whether the class that it&#8217;s part of is <B>public</B>.) So in this case,
when you say <B>java Detergent</B>, <B>Detergent.main(&#160;)</B> will be
called. But you can also say <B>java Cleanser </B>to invoke
<B>Cleanser.main(&#160;)</B>, even though <B>Cleanser</B> is not a <B>public</B>
class. This technique of putting a <B>main(&#160;)</B> in each class allows easy
<A NAME="Index562"></A><A NAME="Index563"></A>unit testing for each class. And
you don&#8217;t need to remove the <B>main(&#160;)</B> when you&#8217;re
finished testing; you can leave it in for later testing.

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

<backtalk:display ID=TIJ3_CHAPTER6_I17>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here, you can see that
<B>Detergent.main(&#160;)</B> calls <B>Cleanser.main(&#160;)</B> explicitly,
passing it the same arguments from the command line (however, you could pass it
any <B>String</B> array). 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I17' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER6_I18>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It&#8217;s important that all of the
methods in <B>Cleanser </B>are <B>public</B>. Remember that if you leave off any
access specifier the member defaults to &#8220;friendly,&#8221; which allows
access only to package members. Thus, <I>within this package</I>, anyone could
use those methods if there were no access specifier. <B>Detergent</B> would have
no trouble, for example. However, if a class from some other package were to
inherit from <B>Cleanser</B> it could access only <B>public </B>members. So to
plan for inheritance, as a general rule make all fields <B>private </B>and all
methods <B>public</B>.<B> </B>(<B>protected </B>members also allow access by
derived classes; you&#8217;ll learn about this later.) Of course, in particular
cases you must make adjustments, but this is a useful guideline.

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

<backtalk:display ID=TIJ3_CHAPTER6_I19>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that <B>Cleanser</B> has a set of
methods in its interface: <B>append(&#160;)</B>, <B>dilute(&#160;)</B>,
<B>apply(&#160;)</B>, <B>scrub(&#160;)</B>, and <B>print(&#160;)</B>. Because
<B>Detergent</B> is <I>derived from</I> <B>Cleanser</B> (via the
<A NAME="Index564"></A><B>extends</B> keyword) it automatically gets all these
methods in its interface, even though you don&#8217;t see them all explicitly
defined in <B>Detergent</B>. You can think of inheritance, then, as <I>reusing
the interface.</I> (The implementation also comes with it, but that part
isn&#8217;t the primary point.)

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

<backtalk:display ID=TIJ3_CHAPTER6_I20>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As seen in <B>scrub(&#160;)</B>,
it&#8217;s possible to take a method that&#8217;s been defined in the base class
and modify it. In this case, you might want to call the method from the base
class inside the new version. But inside <B>scrub(&#160;)</B> you cannot simply
call <B>scrub(&#160;)</B>, since that would produce a recursive call, which
isn&#8217;t what you want. To solve this problem Java has the
<A NAME="Index565"></A>keyword <B>super</B> that refers to the
&#8220;<A NAME="Index566"></A>superclass&#8221; that the current class has been
inherited from. Thus the expression <B>super.scrub(&#160;)</B> calls the
base-class version of the method <B>scrub(&#160;)</B>.

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

<backtalk:display ID=TIJ3_CHAPTER6_I21>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When inheriting you&#8217;re not
restricted to using the methods of the base class. You can also add new methods
to the derived class exactly the way you put any method in a class: just define
it. The method <B>foam(&#160;)</B> is an example of this.

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

<backtalk:display ID=TIJ3_CHAPTER6_I22>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In <B>Detergent.main(&#160;) </B>you can
see that for a <B>Detergent</B> object you can call all the methods that are

⌨️ 快捷键说明

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