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

📄 tij0023.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html><body>

<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0022.html">Prev</a> | <a href="tij0024.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
Interchangeable
objects 
<P>with
polymorphism
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Inheritance
usually ends up creating a family of classes, all based on the same uniform
interface. We express this with an inverted tree diagram:
</FONT><A NAME="fnB5" HREF="#fn5">[5]</A><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
of the most important things you do with such a family of classes is to treat
an object of a derived class as an object of the base class. This is important
because it means you can write a single piece of code that ignores the specific
details of type and talks just to the base class. That code is then 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>decoupled</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
from type-specific information, and thus is simpler to write and easier to
understand. And, if a new type &#8211; a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Triangle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
for example &#8211;
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
added through inheritance, the code you write will work just as well for the
new type of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
as it did on the existing types. Thus the program is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>extensible</I></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">Consider
the above example. If you write a function in Java:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">void</font> doStuff(Shape s) {
  s.erase();
  <font color="#009900">// ...</font>
  s.draw();
}</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
function speaks to any 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so it is independent of the specific type of object it&#8217;s drawing and
erasing. If in some other program we use the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>doStuff(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
function:
</FONT><P></DIV>

<font color="#990000"><PRE>Circle c = <font color="#0000ff">new</font> Circle();
Triangle t = <font color="#0000ff">new</font> Triangle();
Line l = <font color="#0000ff">new</font> Line();
doStuff(c);
doStuff(t);
doStuff(l);</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
calls to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>doStuff(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">automatically
work right, regardless of the exact type of the object. 
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
is actually a pretty amazing trick. Consider the line:
</FONT><P></DIV><DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">doStuff(c);</FONT></TT><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">What&#8217;s
happening here is that a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle is being passed into a function that&#8217;s expecting a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle. Since a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>is</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
it can be treated as one by 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>doStuff(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
That is, any message that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>doStuff(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can send to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can accept. So it is a completely safe and logical thing to do.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">We
call this process of treating a derived type as though it were its base type 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>upcasting</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The name 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>cast
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
used in the sense of casting into a mold and the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>up</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
comes from the way the inheritance diagram is typically arranged, with the base
type at the top and the derived classes fanning out downward. Thus, casting to
a base type is moving up the inheritance diagram: upcasting.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">An
object-oriented program contains some upcasting somewhere, because that&#8217;s
how you decouple yourself from knowing about the exact type you&#8217;re
working with. Look at the code in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>doStuff(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>

<font color="#990000"><PRE>  s.erase();
  <font color="#009900">// ...</font>
  s.draw(); </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Notice
that it doesn&#8217;t say &#8220;If you&#8217;re a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
do this, if you&#8217;re a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Square</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
do that, etc.&#8221; If you write that kind of code, which checks for all the
possible types a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can actually be, it&#8217;s messy and you need to change it every time you add
a new kind of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Here, you just say &#8220;You&#8217;re a shape, I know you can 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>erase(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">yourself,
do it and take care of the details correctly.&#8221; 
</FONT><a name="_Toc375545196"></a><a name="_Toc408018393"></a><P></DIV>
<A NAME="Heading27"></A><H3 ALIGN=LEFT>
Dynamic
binding
</H3>

⌨️ 快捷键说明

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