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

📄 tij0179.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 2 页
字号:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">since
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>tb[i]</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
produces a handle to the base type 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">this
call will end up calling a different method depending on the type of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that&#8217;s currently selected. That is the second dispatch.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here&#8217;s
the base class for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: TypedBin.java</font>
<font color="#009900">// Vector that knows how to grab the right type</font>
<font color="#0000ff">package</font> c16.doubledispatch;
<font color="#0000ff">import</font> c16.trash.*;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">public</font> <font color="#0000ff">abstract</font> <font color="#0000ff">class</font> TypedBin {
  Vector v = <font color="#0000ff">new</font> Vector();
  <font color="#0000ff">protected</font> <font color="#0000ff">boolean</font> addIt(Trash t) {
    v.addElement(t);
    <font color="#0000ff">return</font> <font color="#0000ff">true</font>;
  }
  <font color="#0000ff">public</font> Enumeration elements() {
    <font color="#0000ff">return</font> v.elements();
  }
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDAluminum a) {
    <font color="#0000ff">return</font> <font color="#0000ff">false</font>;
  }
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDPaper a) {
    <font color="#0000ff">return</font> <font color="#0000ff">false</font>;
  }
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDGlass a) {
    <font color="#0000ff">return</font> <font color="#0000ff">false</font>;
  }
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDCardboard a) {
    <font color="#0000ff">return</font> <font color="#0000ff">false</font>;
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see that the overloaded 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>add(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods all return 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>false</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
If the method is not overloaded in a derived class, it will continue to return 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>false</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and the caller (
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addToBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
in this case) will assume that the current 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object has not been added successfully to a collection, and continue searching
for the right collection.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
each of the subclasses of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
only one overloaded method is overridden, according to the type of bin
that&#8217;s being created. For example, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CardboardBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
overrides 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>add(DDCardboard)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The overridden method adds the trash object to its collection and returns 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>true</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
while all the rest of the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>add(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">methods
in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CardboardBin
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">continue
to return 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>false</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
since they haven&#8217;t been overridden. This is another case in which a
parameterized type mechanism in Java would allow automatic generation of code.
(With <A NAME="Index2997"></A><A NAME="Index2998"></A>C++
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>template</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s,
you wouldn&#8217;t have to explicitly write the subclasses or place the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addToBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Since
for this example the trash types have been customized and placed in a different
directory, you&#8217;ll need a different trash data file to make it work.
Here&#8217;s a possible 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DDTrash.dat</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE>c16.DoubleDispatch.DDGlass:54
c16.DoubleDispatch.DDPaper:22
c16.DoubleDispatch.DDPaper:11
c16.DoubleDispatch.DDGlass:17
c16.DoubleDispatch.DDAluminum:89
c16.DoubleDispatch.DDPaper:88
c16.DoubleDispatch.DDAluminum:76
c16.DoubleDispatch.DDCardboard:96
c16.DoubleDispatch.DDAluminum:25
c16.DoubleDispatch.DDAluminum:34
c16.DoubleDispatch.DDGlass:11
c16.DoubleDispatch.DDGlass:68
c16.DoubleDispatch.DDGlass:43
c16.DoubleDispatch.DDAluminum:27
c16.DoubleDispatch.DDCardboard:44
c16.DoubleDispatch.DDAluminum:18
c16.DoubleDispatch.DDPaper:91
c16.DoubleDispatch.DDGlass:63
c16.DoubleDispatch.DDGlass:50
c16.DoubleDispatch.DDGlass:80
c16.DoubleDispatch.DDAluminum:81
c16.DoubleDispatch.DDCardboard:12
c16.DoubleDispatch.DDGlass:12
c16.DoubleDispatch.DDGlass:54
c16.DoubleDispatch.DDAluminum:36
c16.DoubleDispatch.DDAluminum:93
c16.DoubleDispatch.DDGlass:93
c16.DoubleDispatch.DDPaper:80
c16.DoubleDispatch.DDGlass:36
c16.DoubleDispatch.DDGlass:12
c16.DoubleDispatch.DDGlass:60
c16.DoubleDispatch.DDPaper:66
c16.DoubleDispatch.DDAluminum:36
c16.DoubleDispatch.DDCardboard:22</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here&#8217;s
the rest of the program:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: DoubleDispatch.java</font>
<font color="#009900">// Using multiple dispatching to handle more</font>
<font color="#009900">// than one unknown type during a method call.</font>
<font color="#0000ff">package</font> c16.doubledispatch;
<font color="#0000ff">import</font> c16.trash.*;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">class</font> AluminumBin <font color="#0000ff">extends</font> TypedBin {
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDAluminum a) {
    <font color="#0000ff">return</font> addIt(a);
  }
}

<font color="#0000ff">class</font> PaperBin <font color="#0000ff">extends</font> TypedBin {
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDPaper a) {
    <font color="#0000ff">return</font> addIt(a);
  }
}

<font color="#0000ff">class</font> GlassBin <font color="#0000ff">extends</font> TypedBin {
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDGlass a) {
    <font color="#0000ff">return</font> addIt(a);
  }
}

<font color="#0000ff">class</font> CardboardBin <font color="#0000ff">extends</font> TypedBin {
  <font color="#0000ff">public</font> <font color="#0000ff">boolean</font> add(DDCardboard a) {
    <font color="#0000ff">return</font> addIt(a);
  }
}

<font color="#0000ff">class</font> TrashBinSet {
  <font color="#0000ff">private</font> TypedBin[] binSet = {
    <font color="#0000ff">new</font> AluminumBin(),
    <font color="#0000ff">new</font> PaperBin(),
    <font color="#0000ff">new</font> GlassBin(),
    <font color="#0000ff">new</font> CardboardBin()
  };
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> sortIntoBins(Vector bin) {
    Enumeration e = bin.elements();
    <font color="#0000ff">while</font>(e.hasMoreElements()) {
      TypedBinMember t = 
        (TypedBinMember)e.nextElement();
      <font color="#0000ff">if</font>(!t.addToBin(binSet))
        System.err.println("Couldn't add " + t);
    }
  }
  <font color="#0000ff">public</font> TypedBin[] binSet() { <font color="#0000ff">return</font> binSet; }
}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> DoubleDispatch {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Vector bin = <font color="#0000ff">new</font> Vector();
    TrashBinSet bins = <font color="#0000ff">new</font> TrashBinSet();
    <font color="#009900">// ParseTrash still works, without changes:</font>
    ParseTrash.fillBin("DDTrash.dat", bin);
    <font color="#009900">// Sort from the master bin into the </font>
    <font color="#009900">// individually-typed bins:</font>
    bins.sortIntoBins(bin);
    TypedBin[] tb = bins.binSet();
    <font color="#009900">// Perform sumValue for each bin...</font>
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; tb.length; i++)
      Trash.sumValue(tb[i].v);
    <font color="#009900">// ... and for the master bin</font>
    Trash.sumValue(bin);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TrashBinSet</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
encapsulates all of the different types of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s,
along with the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sortIntoBins(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, which is where all the double dispatching takes place. You can see that
once the structure is set up, sorting into the various 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
is remarkably easy. In addition, the efficiency of two dynamic method calls is
probably better than any other way you could sort.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Notice
the ease of use of this system in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
as well as the complete independence of any specific type information within 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
All other methods that talk only to the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
base-class interface will be equally invulnerable to changes in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
types.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
changes necessary to add a new type are relatively isolated: you inherit the
new type of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Trash</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
with its 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addToBin(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, then you inherit a new 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TypedBin</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(this is really just a copy and simple edit), and finally you add a new type
into the aggregate initialization for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TrashBinSet</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><a name="_Toc408018805"></a><P></DIV>

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

⌨️ 快捷键说明

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