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

📄 tij0091.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 2 页
字号:
doesn&#8217;t show up. (The Java 1.2<A NAME="Index816"></A>
collections provide sorting functionality that solves this problem.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Inheritance
(
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>extends</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)
is used here to create a new type of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
&#8211; that is, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SortVector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>is
a 
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
with some added functionality. The use of inheritance here is powerful but it
presents problems. It turns out that some methods are 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">(described
in Chapter 7), so you cannot override them. If you want to create a sorted 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that accepts and produces only 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">objects
you run into a wall, since 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addElement(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>elementAt(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">are
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and these are precisely the methods you&#8217;d need to override so they accept
and produce only 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects. No luck there.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">On
the other hand, consider <A NAME="Index817"></A>composition:
the placing of an object 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>inside</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
a new class. Rather than rewrite the above code to accomplish this, we can
simply use a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SortVector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
inside the new class. In this case, the inner class to implement the interface 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Compare
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">will
be created anonymously:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: StrSortVector.java</font>
<font color="#009900">// Automatically sorted Vector that </font>
<font color="#009900">// accepts and produces only Strings</font>
<font color="#0000ff">package</font> c08;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> StrSortVector {
  <font color="#0000ff">private</font> SortVector v = <font color="#0000ff">new</font> SortVector(
    <font color="#009900">// Anonymous inner class:</font>
    <font color="#0000ff">new</font> Compare() {
      <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> 
      lessThan(Object l, Object r) {
        <font color="#0000ff">return</font> 
          ((String)l).toLowerCase().compareTo(
          ((String)r).toLowerCase()) &lt; 0;
      }
      <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> 
      lessThanOrEqual(Object l, Object r) {
        <font color="#0000ff">return</font> 
          ((String)l).toLowerCase().compareTo(
          ((String)r).toLowerCase()) &lt;= 0;
      }
    }
  );
  <font color="#0000ff">private</font> <font color="#0000ff">boolean</font> sorted = <font color="#0000ff">false</font>;
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> addElement(String s) {
    v.addElement(s);
    sorted = <font color="#0000ff">false</font>;
  }
  <font color="#0000ff">public</font> String elementAt(<font color="#0000ff">int</font> index) {
    <font color="#0000ff">if</font>(!sorted) {
      v.sort();
      sorted = <font color="#0000ff">true</font>;
    }
    <font color="#0000ff">return</font> (String)v.elementAt(index);
  }
  <font color="#0000ff">public</font> Enumeration elements() {
    <font color="#0000ff">if</font>(!sorted) {
      v.sort();
      sorted = <font color="#0000ff">true</font>;
    }
    <font color="#0000ff">return</font> v.elements();
  }
  <font color="#009900">// Test it:</font>
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    StrSortVector sv = <font color="#0000ff">new</font> StrSortVector();
    sv.addElement("d");
    sv.addElement("A");
    sv.addElement("C");
    sv.addElement("c");
    sv.addElement("b");
    sv.addElement("B");
    sv.addElement("D");
    sv.addElement("a");
    Enumeration e = sv.elements();
    <font color="#0000ff">while</font>(e.hasMoreElements())
      System.out.println(e.nextElement());
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
quickly reuses the code from 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SortVector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to create the desired functionality. However, not all of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods from 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>SortVector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
appear in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StrSortVector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
When reusing code this way, you can make a definition in the new class for each
one in the contained class, or you can start with just a few and periodically
go back and add more when you need them. Eventually the new class design will
settle down.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
advantage to this approach is that it will take only
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
String
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects and produce only 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects, and the checking happens at compile time instead of run time. Of
course, that&#8217;s only true for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addElement(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>elementAt(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">;
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>elements(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
still produces an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Enumeration</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that is untyped at compile time. Type checking for the <A NAME="Index818"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Enumeration</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>StrSortVector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
still happens, of course, it just happens at run-time by throwing exceptions if
you do something wrong. It&#8217;s a trade-off: do you find out about something 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>for
sure
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
at compile time or 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>probably</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
at run-time? (That is, &#8220;probably not while you&#8217;re testing the
code&#8221; and &#8220;probably when the program user tries something you
didn&#8217;t test for.&#8221;) Given the choices and the hassle, it&#8217;s
easier to use inheritance and just grit your teeth while casting &#8211; again,
if <A NAME="Index819"></A>parameterized
types are ever added to Java, they will solve this problem.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see there&#8217;s a flag called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sorted</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in this class. You could sort the vector every time 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addElement(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is called, and constantly keep it in a sorted state. But usually people add a
lot of elements to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">before
beginning to read it. So sorting after every 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addElement(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
would be less efficient than waiting until someone wants to read the vector and
then sorting it, which is what is done here. The technique of delaying a
process until it is absolutely necessary is called <A NAME="Index820"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>lazy
evaluation
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
(There is an analogous technique called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>lazy
initialization
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
which waits until a field value is necessary before initializing it.)
</FONT><a name="_Toc408018576"></a><P></DIV>

<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0090.html">Prev</a> | <a href="tij0092.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

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