📄 chap06.htm
字号:
when your class might perform some activities during its lifetime that require
cleanup. As mentioned in Chapter 4, you can’t know when the garbage
collector will be called, or if it will be called. So if you want something
cleaned up for a class, you must explicitly write a special method to do it, and
make sure that the client programmer knows that they must call this method. On
top of this—as described in Chapter 10
(“<A NAME="Index587"></A>Error Handling with Exceptions”)—you
must guard against an exception by putting such cleanup in a
<A NAME="Index588"></A><B>finally</B> clause.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I30'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I31>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Consider an example of a computer-aided
design system that draws pictures on the screen:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c06:CADSystem.java</font>
<font color=#009900>// Ensuring proper cleanup.</font>
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>class</font> Shape {
Shape(<font color=#0000ff>int</font> i) {
System.out.println(<font color=#004488>"Shape constructor"</font>);
}
<font color=#0000ff>void</font> cleanup() {
System.out.println(<font color=#004488>"Shape cleanup"</font>);
}
}
<font color=#0000ff>class</font> Circle <font color=#0000ff>extends</font> Shape {
Circle(<font color=#0000ff>int</font> i) {
<font color=#0000ff>super</font>(i);
System.out.println(<font color=#004488>"Drawing a Circle"</font>);
}
<font color=#0000ff>void</font> cleanup() {
System.out.println(<font color=#004488>"Erasing a Circle"</font>);
<font color=#0000ff>super</font>.cleanup();
}
}
<font color=#0000ff>class</font> Triangle <font color=#0000ff>extends</font> Shape {
Triangle(<font color=#0000ff>int</font> i) {
<font color=#0000ff>super</font>(i);
System.out.println(<font color=#004488>"Drawing a Triangle"</font>);
}
<font color=#0000ff>void</font> cleanup() {
System.out.println(<font color=#004488>"Erasing a Triangle"</font>);
<font color=#0000ff>super</font>.cleanup();
}
}
<font color=#0000ff>class</font> Line <font color=#0000ff>extends</font> Shape {
<font color=#0000ff>private</font> <font color=#0000ff>int</font> start, end;
Line(<font color=#0000ff>int</font> start, <font color=#0000ff>int</font> end) {
<font color=#0000ff>super</font>(start);
<font color=#0000ff>this</font>.start = start;
<font color=#0000ff>this</font>.end = end;
System.out.println(<font color=#004488>"Drawing a Line: "</font> +
start + <font color=#004488>", "</font> + end);
}
<font color=#0000ff>void</font> cleanup() {
System.out.println(<font color=#004488>"Erasing a Line: "</font> +
start + <font color=#004488>", "</font> + end);
<font color=#0000ff>super</font>.cleanup();
}
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> CADSystem <font color=#0000ff>extends</font> Shape {
<font color=#0000ff>private</font> Circle c;
<font color=#0000ff>private</font> Triangle t;
<font color=#0000ff>private</font> Line[] lines = <font color=#0000ff>new</font> Line[10];
CADSystem(<font color=#0000ff>int</font> i) {
<font color=#0000ff>super</font>(i + 1);
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j < 10; j++)
lines[j] = <font color=#0000ff>new</font> Line(j, j*j);
c = <font color=#0000ff>new</font> Circle(1);
t = <font color=#0000ff>new</font> Triangle(1);
System.out.println(<font color=#004488>"Combined constructor"</font>);
}
<font color=#0000ff>void</font> cleanup() {
System.out.println(<font color=#004488>"CADSystem.cleanup()"</font>);
<font color=#009900>// The order of cleanup is the reverse </font>
<font color=#009900>// of the order of initialization</font>
t.cleanup();
c.cleanup();
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = lines.length - 1; i >= 0; i--)
lines[i].cleanup();
<font color=#0000ff>super</font>.cleanup();
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
CADSystem x = <font color=#0000ff>new</font> CADSystem(47);
<font color=#0000ff>try</font> {
<font color=#009900>// Code and exception handling...</font>
} <font color=#0000ff>finally</font> {
x.cleanup();
}
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Everything in this system is some kind of
<B>Shape</B> (which is itself a kind of <B>Object</B> since it’s
implicitly inherited from the root class). Each class redefines
<B>Shape</B>’s <B>cleanup( )</B> method in addition to calling the
base-class version of that method using <B>super</B>. The specific <B>Shape</B>
classes—<B>Circle</B>, <B>Triangle</B> and <B>Line</B>—all have
constructors that “draw,” although any method called during the
lifetime of the object could be responsible for doing something that needs
cleanup. Each class has its own <B>cleanup( )</B> method to restore
nonmemory things back to the way they were before the object existed.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I31'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I32>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In <B>main( )</B>, you can see two
keywords that are new, and won’t officially be introduced until Chapter
10: <A NAME="Index589"></A><B>try</B> and <A NAME="Index590"></A><B>finally</B>.
The <B>try</B> keyword indicates that the block that follows (delimited by curly
braces) is a <I>guarded region</I>, which means that it is given special
treatment. One of these special treatments is that the code in the
<B>finally</B> clause following this guarded region is <I>always</I> executed,
no matter how the <B>try</B> block exits. (With exception handling, it’s
possible to leave a <B>try</B> block in a number of nonordinary ways.) Here, the
<B>finally</B> clause is saying “always call <B>cleanup( )</B> for
<B>x</B>, no matter what happens.” These keywords will be explained
thoroughly in Chapter 10.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I32'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I33>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that in your cleanup method you must
also pay attention to the calling order for the base-class and member-object
cleanup methods in case one subobject depends on another. In general, you should
follow the same form that is imposed by a C++ compiler on its destructors: First
perform all of the cleanup work specific to your class, in the reverse order of
creation. (In general, this requires that base-class elements still be viable.)
Then call the base-class cleanup method, as demonstrated here.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I33'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I34>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There can be many cases in which the
cleanup issue is not a problem; you just let the garbage collector do the work.
But when you must do it explicitly, diligence and attention is required.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I34'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I35>
</FONT><A NAME="_Toc312374020"></A><BR></P></DIV>
<A NAME="Heading214"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Order of garbage collection</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There’s not much you can rely on
when it comes to <A NAME="Index591"></A>garbage collection. The garbage
collector might never be called. If it is, it can reclaim objects in any order
it wants. It’s best to not rely on garbage collection for anything but
memory reclamation. If you want cleanup to take place, make your own cleanup
methods and don’t rely on <A NAME="Index592"></A><B>finalize( )</B>.
(As mentioned in Chapter 4, Java can be forced to call all the finalizers.)
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I35'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I36>
</FONT><A NAME="_Toc312374021"></A><A NAME="_Toc375545311"></A><A NAME="_Toc481064609"></A><BR></P></DIV>
<A NAME="Heading215"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Name hiding</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Only C++ programmers might be surprised
by name hiding, since it works differently in that language.
<A NAME="Index593"></A><A NAME="Index594"></A><A NAME="Index595"></A><A NAME="Index596"></A>If
a Java base class has a method name that’s overloaded several times,
redefining that method name in the derived class will <I>not </I>hide any of the
base-class versions. Thus overloading works regardless of whether the method was
defined at this level or in a base class:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c06:Hide.java</font>
<font color=#009900>// Overloading a base-class method name</font>
<font color=#009900>// in a derived class does not hide the</font>
<font color=#009900>// base-class versions.</font>
<font color=#0000ff>class</font> Homer {
<font color=#0000ff>char</font> doh(<font color=#0000ff>char</font> c) {
System.out.println(<font color=#004488>"doh(char)"</font>);
<font color=#0000ff>return</font> 'd';
}
<font color=#0000ff>float</font> doh(<font color=#0000ff>float</font> f) {
System.out.println(<font color=#004488>"doh(float)"</font>);
<font color=#0000ff>return</font> 1.0f;
}
}
<font color=#0000ff>class</font> Milhouse {}
<font color=#0000ff>class</font> Bart <font color=#0000ff>extends</font> Homer {
<font color=#0000ff>void</font> doh(Milhouse m) {}
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Hide {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Bart b = <font color=#0000ff>new</font> Bart();
b.doh(1); <font color=#009900>// doh(float) used</font>
b.doh('x');
b.doh(1.0f);
b.doh(<font color=#0000ff>new</font> Milhouse());
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As you’ll see in the next chapter,
it’s far more common to override methods of the same name using exactly
the same signature and return type as in the base class. It can be confusing
otherwise (which is why C++ disallows it, to prevent you from making what is
probably a mistake).
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I36'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I37>
</FONT><A NAME="_Toc305593255"></A><A NAME="_Toc305628727"></A><A NAME="_Toc312374023"></A><A NAME="_Toc375545312"></A><A NAME="_Toc481064610"></A><BR></P></DIV>
<A NAME="Heading216"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Choosing composition <BR>vs.
inheritance<BR><A NAME="Index597"></A><A NAME="Index598"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Both composition and inheritance allow
you to place subobjects<A NAME="Index599"></A> inside your new class. You might
wonder about the difference between the two, and when to choose one over the
other.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I37'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I38>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Composition is generally used when you
want the features of an existing class inside your new class, but not its
interface. That is, you embed an object so that you can use it to implement
functionality in your new class, but the user of your new class sees the
interface you’ve defined for the new class rather than the interface from
the embedded object. For this effect, you embed <B>private</B> objects of
existing classes inside your new class.
<A NAME="Index600"></A><A NAME="Index601"></A>
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I38'
target="_blank">Add Comment</a> ]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -