📄 chap06.htm
字号:
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c06:Bath.java</font>
<font color=#009900>// Constructor initialization with composition.</font>
<font color=#0000ff>class</font> Soap {
<font color=#0000ff>private</font> String s;
Soap() {
System.out.println(<font color=#004488>"Soap()"</font>);
s = <font color=#0000ff>new</font> String(<font color=#004488>"Constructed"</font>);
}
<font color=#0000ff>public</font> String toString() { <font color=#0000ff>return</font> s; }
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Bath {
<font color=#0000ff>private</font> String
<font color=#009900>// Initializing at point of definition:</font>
s1 = <font color=#0000ff>new</font> String(<font color=#004488>"Happy"</font>),
s2 = <font color=#004488>"Happy"</font>,
s3, s4;
Soap castille;
<font color=#0000ff>int</font> i;
<font color=#0000ff>float</font> toy;
Bath() {
System.out.println(<font color=#004488>"Inside Bath()"</font>);
s3 = <font color=#0000ff>new</font> String(<font color=#004488>"Joy"</font>);
i = 47;
toy = 3.14f;
castille = <font color=#0000ff>new</font> Soap();
}
<font color=#0000ff>void</font> print() {
<font color=#009900>// Delayed initialization:</font>
<font color=#0000ff>if</font>(s4 == <font color=#0000ff>null</font>)
s4 = <font color=#0000ff>new</font> String(<font color=#004488>"Joy"</font>);
System.out.println(<font color=#004488>"s1 = "</font> + s1);
System.out.println(<font color=#004488>"s2 = "</font> + s2);
System.out.println(<font color=#004488>"s3 = "</font> + s3);
System.out.println(<font color=#004488>"s4 = "</font> + s4);
System.out.println(<font color=#004488>"i = "</font> + i);
System.out.println(<font color=#004488>"toy = "</font> + toy);
System.out.println(<font color=#004488>"castille = "</font> + castille);
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Bath b = <font color=#0000ff>new</font> Bath();
b.print();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that in the <B>Bath </B>constructor
a statement is executed before any of the initializations take place. When you
don’t initialize at the point of definition, there’s still no
guarantee that you’ll perform any initialization before you send a message
to an object reference—except for the inevitable run-time exception.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I11'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I12>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here’s the output for the
program:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Inside Bath()
Soap()
s1 = Happy
s2 = Happy
s3 = Joy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When <B>print( )</B> is called it
fills in <B>s4</B> so that all the fields are properly initialized by the time
they are used.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I12'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I13>
</FONT><A NAME="_Toc305593252"></A><A NAME="_Toc305628724"></A><A NAME="_Toc312374015"></A><A NAME="_Toc375545307"></A><A NAME="_Toc481064605"></A><BR></P></DIV>
<A NAME="Heading208"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Inheritance syntax<BR><A NAME="Index553"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Inheritance is an integral part of Java
(and OOP languages in general). It turns out that you’re always doing
inheritance when you create a class, because unless you explicitly inherit from
some other class, you implicitly inherit from Java’s
<A NAME="Index554"></A>standard root class <B>Object</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I13'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I14>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The syntax for composition is obvious,
but to perform inheritance there’s a distinctly different form. When you
inherit, you say “This new class is like that old class.” You state
this in code by giving the name of the class as usual, but before the opening
brace of the class body, put the <A NAME="Index555"></A>keyword <B>extends</B>
followed by the name of the
<A NAME="Index556"></A><A NAME="Index557"></A><I>base class</I>. When you do
this, you automatically get all the data members and methods in the base class.
Here’s an example:
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I14'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I15>
</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c06:Detergent.java</font>
<font color=#009900>// Inheritance syntax & properties.</font>
<font color=#0000ff>class</font> Cleanser {
<font color=#0000ff>private</font> String s = <font color=#0000ff>new</font> String(<font color=#004488>"Cleanser"</font>);
<font color=#0000ff>public</font> <font color=#0000ff>void</font> append(String a) { s += a; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> dilute() { append(<font color=#004488>" dilute()"</font>); }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> apply() { append(<font color=#004488>" apply()"</font>); }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> scrub() { append(<font color=#004488>" scrub()"</font>); }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> print() { System.out.println(s); }
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Cleanser x = <font color=#0000ff>new</font> Cleanser();
x.dilute(); x.apply(); x.scrub();
x.print();
}
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Detergent <font color=#0000ff>extends</font> Cleanser {
<font color=#009900>// Change a method:</font>
<font color=#0000ff>public</font> <font color=#0000ff>void</font> scrub() {
append(<font color=#004488>" Detergent.scrub()"</font>);
<font color=#0000ff>super</font>.scrub(); <font color=#009900>// Call base-class version</font>
}
<font color=#009900>// Add methods to the interface:</font>
<font color=#0000ff>public</font> <font color=#0000ff>void</font> foam() { append(<font color=#004488>" foam()"</font>); }
<font color=#009900>// Test the new class:</font>
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Detergent x = <font color=#0000ff>new</font> Detergent();
x.dilute();
x.apply();
x.scrub();
x.foam();
x.print();
System.out.println(<font color=#004488>"Testing base class:"</font>);
Cleanser.main(args);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This demonstrates a number of features.
First, in the <B>Cleanser</B> <B>append( )</B> method, <B>String</B>s are
concatenated to <B>s</B> using the <B>+=</B> operator, which is one of the
operators (along with ‘<B>+</B>’) that the Java designers
“overloaded” to work with
<A NAME="Index558"></A><A NAME="Index559"></A><A NAME="Index560"></A><B>String</B>s.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I15'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I16>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Second, both <B>Cleanser</B> and
<B>Detergent</B> contain a <A NAME="Index561"></A><B>main( )</B> method.
You can create a <B>main( )</B> for each one of your classes, and
it’s often recommended to code this way so that your test code is wrapped
in with the class. Even if you have a lot of classes in a program, only the
<B>main( )</B> for the class invoked on the command line will be called.
(As long as <B>main( )</B> is <B>public</B>, it doesn’t matter
whether the class that it’s part of is <B>public</B>.) So in this case,
when you say <B>java Detergent</B>, <B>Detergent.main( )</B> will be
called. But you can also say <B>java Cleanser </B>to invoke
<B>Cleanser.main( )</B>, even though <B>Cleanser</B> is not a <B>public</B>
class. This technique of putting a <B>main( )</B> in each class allows easy
<A NAME="Index562"></A><A NAME="Index563"></A>unit testing for each class. And
you don’t need to remove the <B>main( )</B> when you’re
finished testing; you can leave it in for later testing.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I16'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I17>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here, you can see that
<B>Detergent.main( )</B> calls <B>Cleanser.main( )</B> explicitly,
passing it the same arguments from the command line (however, you could pass it
any <B>String</B> array).
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I17'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I18>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It’s important that all of the
methods in <B>Cleanser </B>are <B>public</B>. Remember that if you leave off any
access specifier the member defaults to “friendly,” which allows
access only to package members. Thus, <I>within this package</I>, anyone could
use those methods if there were no access specifier. <B>Detergent</B> would have
no trouble, for example. However, if a class from some other package were to
inherit from <B>Cleanser</B> it could access only <B>public </B>members. So to
plan for inheritance, as a general rule make all fields <B>private </B>and all
methods <B>public</B>.<B> </B>(<B>protected </B>members also allow access by
derived classes; you’ll learn about this later.) Of course, in particular
cases you must make adjustments, but this is a useful guideline.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I18'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I19>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that <B>Cleanser</B> has a set of
methods in its interface: <B>append( )</B>, <B>dilute( )</B>,
<B>apply( )</B>, <B>scrub( )</B>, and <B>print( )</B>. Because
<B>Detergent</B> is <I>derived from</I> <B>Cleanser</B> (via the
<A NAME="Index564"></A><B>extends</B> keyword) it automatically gets all these
methods in its interface, even though you don’t see them all explicitly
defined in <B>Detergent</B>. You can think of inheritance, then, as <I>reusing
the interface.</I> (The implementation also comes with it, but that part
isn’t the primary point.)
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I19'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I20>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As seen in <B>scrub( )</B>,
it’s possible to take a method that’s been defined in the base class
and modify it. In this case, you might want to call the method from the base
class inside the new version. But inside <B>scrub( )</B> you cannot simply
call <B>scrub( )</B>, since that would produce a recursive call, which
isn’t what you want. To solve this problem Java has the
<A NAME="Index565"></A>keyword <B>super</B> that refers to the
“<A NAME="Index566"></A>superclass” that the current class has been
inherited from. Thus the expression <B>super.scrub( )</B> calls the
base-class version of the method <B>scrub( )</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I20'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I21>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When inheriting you’re not
restricted to using the methods of the base class. You can also add new methods
to the derived class exactly the way you put any method in a class: just define
it. The method <B>foam( )</B> is an example of this.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER6_I21'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER6_I22>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In <B>Detergent.main( ) </B>you can
see that for a <B>Detergent</B> object you can call all the methods that are
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -