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

📄 chap01.htm

📁 Thinking in Java, 2nd edition
💻 HTM
📖 第 1 页 / 共 5 页
字号:
binding</I>. When you send a message to an object, the code being called
isn&#8217;t determined until run-time. The compiler does ensure that the
function exists and performs type checking on the arguments and return value (a
language in which this isn&#8217;t true is called
<A NAME="Index97"></A><A NAME="Index98"></A><I>weakly typed</I>), but it
doesn&#8217;t know the exact code to
execute.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I55' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I56>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To perform late binding, Java uses a
special bit of code in lieu of the absolute call. This code calculates the
address of the function body, using information stored in the object (this
process is covered in great detail in Chapter 7). Thus, each object can behave
differently according to the contents of that special bit of code. When you send
a message to an object, the object actually does figure out what to do with that
message.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I56' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I57>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In some languages (C++, in particular)
you must explicitly state that you want a function to have the flexibility of
late-binding properties. In these languages, by default, member functions are
<I>not</I> dynamically bound. This caused problems, so in Java dynamic binding
is the default and you don&#8217;t need to remember to add any extra keywords in
order to get polymorphism.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I57' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I58>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Consider the shape example. The family of
classes (all based on the same uniform interface) was diagrammed earlier in this
chapter. To demonstrate polymorphism, we want to write a single piece of code
that ignores the specific details of type and talks only to the base class. That
code is <A NAME="Index99"></A><I>decoupled</I> from type-specific information,
and thus is simpler to write and easier to understand. And, if a new
type&#8212;a <B>Hexagon</B>, for example&#8212;is added through inheritance, the
code you write will work just as well for the new type of <B>Shape</B> as it did
on the existing types. Thus, the program is
<I>extensible</I>.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I58' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I59>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you write a method in Java (as you
will soon learn how to do):
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I59' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

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

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>void</font> doStuff(Shape s) {
  s.erase();
  <font color=#009900>// ...</font>
  s.draw();
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This function speaks to any <B>Shape</B>,
so it is independent of the specific type of object that it&#8217;s drawing and
erasing. If in some other part of the program we use the <B>doStuff(&#160;)</B>
function:
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I60' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

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

<BLOCKQUOTE><FONT SIZE = "+1"><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></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The calls to <B>doStuff(&#160;)
</B>automatically work correctly, regardless of the exact type of the object.

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

<backtalk:display ID=TIJ3_CHAPTER1_I62>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This is actually a pretty amazing trick.
Consider the line:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>doStuff(c);</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What&#8217;s happening here is that a
<B>Circle</B> is being passed into a function that&#8217;s expecting a
<B>Shape</B>. Since a <B>Circle</B> <I>is</I> a <B>Shape</B> it can be treated
as one by <B>doStuff(&#160;)</B>. That is, any message that
<B>doStuff(&#160;)</B> can send to a <B>Shape</B>, a <B>Circle</B> can accept.
So it is a completely safe and logical thing to
do.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I62' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I63>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">We call this process of treating a
derived type as though it were its base type
<A NAME="Index100"></A><I>upcasting</I>. The name <A NAME="Index101"></A><I>cast
</I>is used in the sense of casting into a mold and the <I>up</I> comes from the
way the <A NAME="Index102"></A><A NAME="Index103"></A>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:
&#8220;upcasting.&#8221;
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I63' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I64>
</FONT><BR></P></DIV>
<DIV ALIGN="CENTER"><FONT FACE="Georgia"><IMG SRC="TIJ211.gif"></FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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
<B>doStuff(&#160;)</B>:
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I64' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

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

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>  s.erase();
  <font color=#009900>// ...</font>
  s.draw();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice that it doesn&#8217;t say
&#8220;If you&#8217;re a <B>Circle</B>, do this, if you&#8217;re a
<B>Square</B>, do that, etc.&#8221; If you write that kind of code, which checks
for all the possible types that a <B>Shape</B> can actually be, it&#8217;s messy
and you need to change it every time you add a new kind of <B>Shape</B>. Here,
you just say &#8220;You&#8217;re a shape, I know you can <B>erase(&#160;)
</B>and <B>draw(&#160;) </B>yourself, do it, and take care of the details
correctly.&#8221; 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I65' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I66>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What&#8217;s impressive about the code in
<B>doStuff(&#160;)</B> is that, somehow, the right thing happens. Calling
<B>draw(&#160;)</B> for <B>Circle</B> causes different code to be executed than
when calling <B>draw(&#160;) </B>for a <B>Square</B> or a <B>Line</B>, but when
the <B>draw(&#160;)</B> message is sent to an anonymous <B>Shape</B>, the
correct behavior occurs based on the actual type of the <B>Shape</B>. This is
amazing because, as mentioned earlier, when the Java compiler is compiling the
code for <B>doStuff(&#160;)</B>, it cannot know exactly what types it is dealing
with. So ordinarily, you&#8217;d expect it to end up calling the version of
<B>erase(&#160;)</B> and <B>draw(&#160;) </B>for the base class <B>Shape</B>,
and not for the specific <B>Circle</B>, <B>Square</B>, or <B>Line</B>. And yet
the right thing happens because of polymorphism. The compiler and run-time
system handle the details; all you need to know is that it happens, and more
important how to design with it. When you send a message to an object, the
object will do the right thing, even when upcasting is
involved.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I66' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I67>
</FONT><A NAME="_Toc375545197"></A><A NAME="_Toc473421287"></A><A NAME="_Toc481064474"></A><BR></P></DIV>
<A NAME="Heading29"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Abstract base classes and interfaces</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Often in a design, you want the base
class to present <I>only</I> an interface for its derived classes. That is, you
don&#8217;t want anyone to actually create an object of the base class, only to
upcast to it so that its interface can be used. This is accomplished by making
that class <I>abstract </I>using the <B>abstract</B> keyword. If anyone tries to
make an object of an <B>abstract</B> class, the compiler prevents them. This is
a tool to enforce a particular
design.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I67' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I68>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can also use the <B>abstract</B>
keyword to describe a method that hasn&#8217;t been implemented yet&#8212;as a
stub indicating &#8220;here is an interface function for all types inherited
from this class, but at this point I don&#8217;t have any implementation for
it.&#8221; An <B>abstract </B>method may be created only inside an <B>abstract
</B>class. When the class is inherited, that method must be implemented, or the
inheriting class becomes <B>abstract</B> as well. Creating an <B>abstract</B>
method allows you to put a method in an interface without being forced to
provide a possibly meaningless body of code for that
method.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I68' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I69>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>interface</B> keyword takes the
concept of an <B>abstract</B> class one step further by preventing any function
definitions at all. The <B>interface</B> is a very handy and commonly used tool,
as it provides the perfect separation of interface and implementation. In
addition, you can combine many interfaces together, if you wish, whereas
inheriting from multiple regular classes or abstract classes is not
possible.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I69' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I70>
</FONT><A NAME="_Toc375545198"></A><A NAME="_Toc408018395"></A><A NAME="_Toc408018408"></A><A NAME="_Toc312373795"></A><A NAME="_Toc481064475"></A><BR></P></DIV>
<A NAME="Heading30"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Object landscapes and lifetimes</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Technically, OOP is just about abstract
data typing, inheritance, and polymorphism, but other issues can be at least as
important. The remainder of this section will cover these
issues.
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER1_I70' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER1_I71>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"

⌨️ 快捷键说明

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