📄 tij0058.html
字号:
method! You’d typically think that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Pie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are friendly and therefore not available to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cake</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
They
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>are</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
friendly – that part is correct. The reason that they are available in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cake.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is because they are in the same directory and have no explicit package name.
Java treats files like this as implicitly part of the “default
package” for that directory, and therefore friendly to all the other
files in that directory.
</FONT><a name="_Toc375545298"></a><a name="_Toc408018502"></a><P></DIV>
<A NAME="Heading174"></A><H3 ALIGN=LEFT>
private:
you can’t touch that!
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
<A NAME="Index392"></A>keyword
that means no one can access that member except that particular class, inside
methods of that class. Other classes in the same package cannot access
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">members,
so it’s as if you’re even insulating the class against yourself. On
the other hand, it’s not unlikely that a package might be created by
several people collaborating together, so
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
allows you to freely change that member without concern that it will affect
another class in the same package. The default “friendly” package
access is often an adequate amount of hiding; remember, a
“friendly” member is inaccessible to the user of the package. This
is nice, since the default access is the one that you normally use. Thus,
you’ll typically think about access for the members that you explicitly
want to make
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for the client programmer, and as a result, you might not
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">initially
think you’ll use the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">keyword
often since it’s tolerable to get away without it. (This is a distinct
contrast with C++.) However, it turns out that the consistent use of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is very important, especially where multithreading is concerned. (As
you’ll see in Chapter 14.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Here’s
an example of the use of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: IceCream.java</font>
<font color="#009900">// Demonstrates "private" keyword</font>
<font color="#0000ff">class</font> Sundae {
<font color="#0000ff">private</font> Sundae() {}
<font color="#0000ff">static</font> Sundae makeASundae() {
<font color="#0000ff">return</font> <font color="#0000ff">new</font> Sundae();
}
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> IceCream {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#009900">//! Sundae x = new Sundae();</font>
Sundae x = Sundae.makeASundae();
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
shows an example in which
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
comes in handy: you might want to control how an object is created and prevent
someone from directly accessing a particular constructor (or all of them). In
the example above, you cannot create a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Sundae</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object via its constructor; instead you must call the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>makeASundae( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method to do it for you.
</FONT><A NAME="fnB25" HREF="#fn25">[25]</A><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Any
method that you’re certain is only a “helper” method for that
class can be made
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to ensure that you don’t accidentally use it elsewhere in the package and
thus prohibit you from changing or removing the method. Making a method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
guarantees that you retain this option. (However, just because the handle is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn't mean that some other object can't have a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle to the same object. See Chapter 12 for issues about aliasing.)
</FONT><a name="_Toc312373839"></a><a name="_Toc375545299"></a><a name="_Toc408018503"></a><P></DIV>
<A NAME="Heading175"></A><H3 ALIGN=LEFT>
protected:
“sort of friendly”
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
access specifier requires a jump ahead to understand<A NAME="Index393"></A>.
First, you should be aware that you don’t need to understand this section
to continue through the book up through the inheritance chapter. But for
completeness, here is a brief description and example using
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></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">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword deals with a concept called <A NAME="Index394"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>inheritance</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which takes an existing class and adds new members to that class without
touching the existing class, which we refer to as the <A NAME="Index395"></A><A NAME="Index396"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>base</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>class</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You can also change the behavior of existing members of the class. To inherit
from an existing class, you say that your new class <A NAME="Index397"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>extends
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">an
existing class, like this:
</FONT><P></DIV><DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">class
Foo extends Bar {
</FONT></TT><P></DIV><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
rest of the class definition looks the same.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you create a new package and you inherit from a class in another package, the
only members you have access to are the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
members of the original package. (Of course, if you perform the inheritance in
the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>same</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
package, you have the normal package access to all the “friendly”
members.) Sometimes the creator of the base class would like to take a
particular member and grant access to derived classes but not the world in
general. That’s what
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
does. If you refer back to the file
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
on page
<A HREF=" PAGE#_Ref351419800">203</A>,
the following class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>cannot</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
access the “friendly” member:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: ChocolateChip.java</font>
<font color="#009900">// Can't access friendly member</font>
<font color="#009900">// in another class</font>
<font color="#0000ff">import</font> c05.dessert.*;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> ChocolateChip <font color="#0000ff">extends</font> Cookie {
<font color="#0000ff">public</font> ChocolateChip() {
System.out.println(
"ChocolateChip constructor");
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
ChocolateChip x = <font color="#0000ff">new</font> ChocolateChip();
<font color="#009900">//! x.foo(); // Can't access foo</font>
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
of the interesting things about inheritance is that if a method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>foo( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
exists in class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
then it also exists in any class inherited from
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
But since
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>foo( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is “friendly” in a foreign package, it’s unavailable to us in
this one. Of course, you could make it
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but then everyone would have access and maybe that’s not what you want.
If we change the class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
as follows:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#0000ff">public</font> <font color="#0000ff">class</font> Cookie {
<font color="#0000ff">public</font> Cookie() {
System.out.println("Cookie constructor");
}
<font color="#0000ff">protected</font> <font color="#0000ff">void</font> foo() {
System.out.println("foo");
}
}</PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">then
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>foo( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
still has “friendly” access within package
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dessert</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but it is also accessible to anyone inheriting from
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
However, it is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><a name="_Toc375545301"></a><a name="_Toc408018504"></a><P></DIV>
<HR><DIV ALIGN=LEFT><A NAME="fn25" HREF="#fnB25">[25]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
There’s another effect in this case: Since the default constructor is the
only one defined, and it’s
</FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">,
it will prevent inheritance of this class. (A subject that will be introduced
in Chapter 6.)
</FONT><P></DIV>
<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0057.html">Prev</a> | <a href="tij0059.html">Next</a>
</div>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -