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

📄 tij309.htm

📁 这也是我们java老师给我们的thinking in java的一些资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<!--
This document was converted from RTF source: 
By r2net 5.8 r2netcmd Windows 
See http://www.logictran.com
-->
<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Thinking in Java, 3rd ed. Revision 4.0: 7: Polymorphism</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css"></head>

<body >
   <CENTER>     <a href="http://www.MindView.net">     <img src="mindview.gif" alt="MindView Inc." BORDER = "0"></a>     <Font FACE="Verdana, Tahoma, Arial, Helvetica, Sans">     <h2>Thinking in Java, 3<sup>rd</sup> ed. Revision 4.0</h2>     <FONT size = "-1"><br>     [ <a href="README.txt">Viewing Hints</a> ]     [ <a href="http://www.mindview.net/Books/TIJ/">Book Home Page</a> ]     [ <a href="http://www.mindview.net/Etc/MailingList.html">Free Newsletter</a> ] <br>     [ <a href="http://www.mindview.net/Seminars">Seminars</a> ]     [ <a href="http://www.mindview.net/CDs">Seminars on CD ROM</a> ]     [ <a href="http://www.mindview.net/Services">Consulting</a> ] <br><br>     </FONT></FONT>   </CENTER> 
<font face="Georgia"><div align="CENTER"><a href="TIJ308.htm" target="RightFrame"><img src="./prev.gif" alt="Previous " border="0"></a>
<a href="TIJ310.htm" target="RightFrame"><img src="./next.gif" alt="Next " border="0"></a>

<a href="TIJ3_t.htm"><img src="./first.gif" alt="Title Page " border="0"></a>
<a href="TIJ3_i.htm"><img src="./index.gif" alt="Index " border="0"></a>
<a href="TIJ3_c.htm"><img src="./contents.gif" alt="Contents " border="0"></a>
</div>
<hr>

<h1>
<a name="_Toc375545326"></a><a name="_Toc24272646"></a><a name="_Toc24775655"></a><a name="Heading5982"></a>7:
Polymorphism<br></h1>
<p class="Intro"><a name="Index607"></a>Polymorphism is the third essential feature of an object-oriented programming language, after data abstraction and inheritance. <br></p>
<p>It provides another dimension of separation of interface from implementation, to decouple <i>what</i> from <i>how</i>. Polymorphism allows improved code organization and readability as well as the creation of <i>extensible</i> programs that can be &#147;grown&#148; not only during the original creation of the project, but also when new features are desired. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1019" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Encapsulation creates new data types by combining characteristics and behaviors. Implementation hiding separates the interface from the implementation by making the details <b>private</b>. This sort of mechanical organization makes ready sense to someone with a procedural programming background. But polymorphism deals with decoupling in terms of <a name="Index608"></a><i>types</i>. In the last chapter, you saw how inheritance allows the treatment of an object as its own type <a name="Index609"></a><i>or</i> its base type. This ability is critical because it allows many types (derived from the same base type) to be treated as if they were one type, and a single piece of code to work on all those different types equally. The polymorphic method call allows one type to express its distinction from another, similar type, as long as they&#146;re both derived from the same base type. This distinction is expressed through differences in behavior of the methods that you can call through the base class. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1020" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index610"></a>In this chapter, you&#146;ll learn about polymorphism (also called <a name="Index611"></a><a name="Index612"></a><a name="Index613"></a><a name="Index614"></a><i>dynamic binding</i> or <i>late binding</i> or <i>run-time binding</i>)<i> </i>starting from the basics, with simple examples that strip away everything but the polymorphic behavior of the program. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1021" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc305593263"></a><a name="_Toc305628735"></a><a name="_Toc312374040"></a><a name="_Toc375545327"></a><a name="_Toc24775656"></a><a name="Heading5987"></a>Upcasting
revisited</h2>
<p>In Chapter 6 you saw how an object can be used as its own type or as an object of its base type. Taking an object reference and treating it as a reference to its base type is called <i>upcasting</i> because of the way inheritance trees are drawn with the base class at the top. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1022" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index615"></a>You also saw a problem arise, which is embodied in the following example about musical instruments. Since several examples play <b>Note</b>s, we should create the <b>Note</b> class separately, in a package:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:music:Note.java</font>
<font color=#009900>// Notes to play on musical instruments.</font>
<font color=#0000ff>package</font> c07.music;
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Note {
  <font color=#0000ff>private</font> String noteName;
  <font color=#0000ff>private</font> Note(String noteName) {
    <font color=#0000ff>this</font>.noteName = noteName;
  }
  <font color=#0000ff>public</font> String toString() { <font color=#0000ff>return</font> noteName; }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>final</font> Note
    MIDDLE_C = <font color=#0000ff>new</font> Note(<font color=#004488>"Middle C"</font>),
    C_SHARP  = <font color=#0000ff>new</font> Note(<font color=#004488>"C Sharp"</font>),
    B_FLAT   = <font color=#0000ff>new</font> Note(<font color=#004488>"B Flat"</font>);
    <font color=#009900>// Etc.</font>
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>This is an &#147;enumeration&#148; class, which has a fixed number of constant objects to choose from. You can&#146;t make additional objects because the constructor is private. <br></p>
<p>In the following example, <b>Wind</b> is a type of <b>Instrument</b>, therefore <b>Wind</b> is inherited from <b>Instrument</b>:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:music:Music.java</font>
<font color=#009900>// Inheritance &amp; upcasting.</font>
<font color=#0000ff>package</font> c07.music;
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Music {
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Instrument i) {
    <font color=#009900>// ...</font>
    i.play(Note.MIDDLE_C);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Wind flute = <font color=#0000ff>new</font> Wind();
    tune(flute); <font color=#009900>// Upcasting</font>
    monitor.expect(<font color=#0000ff>new</font> String[] {
      <font color=#004488>"Wind.play() Middle C"</font>
    });
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:music:Wind.java</font>
<font color=#0000ff>package</font> c07.music;

<font color=#009900>// Wind objects are instruments</font>
<font color=#009900>// because they have the same interface:</font>
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Wind <font color=#0000ff>extends</font> Instrument {
  <font color=#009900>// Redefine interface method:</font>
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> play(Note n) {
    System.out.println(<font color=#004488>"Wind.play() "</font> + n);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:music:Music.java</font>
<font color=#009900>// Inheritance &amp; upcasting.</font>
<font color=#0000ff>package</font> c07.music;
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Music {
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Instrument i) {
    <font color=#009900>// ...</font>
    i.play(Note.MIDDLE_C);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Wind flute = <font color=#0000ff>new</font> Wind();
    tune(flute); <font color=#009900>// Upcasting</font>
    monitor.expect(<font color=#0000ff>new</font> String[] {
      <font color=#004488>"Wind.play() Middle C"</font>
    });
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The method <b>Music.tune(&#160;)</b> accepts an <b>Instrument </b>reference, but also anything derived from <b>Instrument</b>. In <b>main(&#160;)</b>, you can see this happening as a <b>Wind</b> reference is passed to <b>tune(&#160;)</b>, with no cast necessary. This is acceptable&#151;the interface in <b>Instrument</b> must exist in <b>Wind</b>, because <b>Wind</b> is inherited from <b>Instrument</b>. Upcasting from <b>Wind</b> to <b>Instrument</b> may &#147;narrow&#148; that interface, but it cannot make it anything less than the full interface to <b>Instrument</b>. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap07_1023" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc24775657"></a><a name="Heading6063"></a>Forgetting the object
type</h3>
<p><b>Music.java</b> might seem strange to you. Why should anyone intentionally <i>forget</i> the type of an object? This is what happens when you upcast, and it seems like it could be much more straightforward if <b>tune(&#160;)</b> simply takes a <b>Wind</b> reference as its argument. This brings up an essential point: If you did that, you&#146;d need to write a new <b>tune(&#160;)</b> for every type of <b>Instrument</b> in your system. Suppose we follow this reasoning and add <b>Stringed</b> and <b>Brass</b> instruments: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0114" title="Send BackTalk Comment">Feedback</a></font><br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c07:music:Music2.java</font>
<font color=#009900>// Overloading instead of upcasting.</font>
<font color=#0000ff>package</font> c07.music;
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;

<font color=#0000ff>class</font> Stringed <font color=#0000ff>extends</font> Instrument {
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> play(Note n) {
    System.out.println(<font color=#004488>"Stringed.play() "</font> + n);
  }
}

<font color=#0000ff>class</font> Brass <font color=#0000ff>extends</font> Instrument {
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> play(Note n) {
    System.out.println(<font color=#004488>"Brass.play() "</font> + n);
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Music2 {
  <font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Wind i) {
    i.play(Note.MIDDLE_C);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Stringed i) {
    i.play(Note.MIDDLE_C);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Brass i) {
    i.play(Note.MIDDLE_C);
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Wind flute = <font color=#0000ff>new</font> Wind();

⌨️ 快捷键说明

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