📄 chap05.htm
字号:
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">you can create a <B>Cookie</B> object,
since its constructor is <B>public</B> and the class is <B>public</B>.
(We’ll look more at the concept of a <B>public</B> class later.) However,
the <B>bite( )</B> member is inaccessible inside <B>Dinner.java</B> since
<B>bite( )</B> is friendly only within package <B>dessert</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I49'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I50>
</FONT><BR></P></DIV>
<A NAME="Heading199"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
The default
package<BR><A NAME="Index506"></A><A NAME="Index507"></A><A NAME="Index508"></A></H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You might be surprised to discover that
the following code compiles, even though it would appear that it breaks the
rules:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c05:Cake.java</font>
<font color=#009900>// Accesses a class in a </font>
<font color=#009900>// separate compilation unit.</font>
<font color=#0000ff>class</font> Cake {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Pie x = <font color=#0000ff>new</font> Pie();
x.f();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In a second file, in the same
directory:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c05:Pie.java</font>
<font color=#009900>// The other class.</font>
<font color=#0000ff>class</font> Pie {
<font color=#0000ff>void</font> f() { System.out.println(<font color=#004488>"Pie.f()"</font>); }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You might initially view these as
completely foreign files, and yet <B>Cake</B> is able to create a <B>Pie</B>
object and call its <B>f( )</B> method! (Note that you must have
‘.’ in your CLASSPATH in order for the files to compile.)
You’d typically think that <B>Pie</B> and <B>f( )</B> are friendly
and therefore not available to <B>Cake</B>. They <I>are</I> friendly—that
part is correct. The reason that they are available in <B>Cake.java</B> 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.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I50'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I51>
</FONT><A NAME="_Toc375545298"></A><A NAME="_Toc481064597"></A><BR></P></DIV>
<A NAME="Heading200"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
private: you can’t touch that!</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>private</B>
<A NAME="Index509"></A>keyword means that no one can access that member except
that particular class, inside methods of that class. Other classes in the same
package cannot access <B>private </B>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 <B>private</B> allows you to freely change that member without
concern that it will affect another class in the same package.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I51'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I52>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The default “friendly”
package access often provides 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 (and the one
that you’ll get if you forget to add any access control). Thus,
you’ll typically think about access for the members that you explicitly
want to make <B>public</B> for the client programmer, and as a result, you might
not<I> </I>initially think you’ll use the <B>private </B>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 <B>private</B> is
very important, especially where multithreading is concerned. (As you’ll
see in Chapter 14.)
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I52'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I53>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here’s an example of the use of
<B>private</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c05: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>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This shows an example in which
<B>private</B> 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 <B>Sundae</B> object via
its constructor; instead you must call the <B>makeASundae( )</B> method to
do it for you</FONT><A NAME="fnB33" HREF="#fn33">[33]</A><FONT FACE="Georgia">.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I53'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I54>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Any method that you’re certain is
only a “helper” method for that class can be made <B>private,</B> to
ensure that you don’t accidentally use it elsewhere in the package and
thus prohibit yourself from changing or removing the method. Making a method
<B>private</B> guarantees that you retain this option.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I54'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I55>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The same is true for a <B>private
</B>field inside a class. Unless you must expose the underlying implementation
(which is a much rarer situation than you might think), you should make all
fields <B>private</B>. However, just because a reference to an object is
<B>private</B> inside a class doesn't mean that some other object can't have a
<B>public</B> reference to the same object. (See Appendix A for issues about
aliasing.)
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I55'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I56>
</FONT><A NAME="_Toc312373839"></A><A NAME="_Toc375545299"></A><A NAME="_Toc481064598"></A><BR></P></DIV>
<A NAME="Heading201"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
protected: “sort of friendly”</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>protected</B> access specifier
requires a jump ahead to understand<A NAME="Index510"></A>. First, you should be
aware that you don’t need to understand this section to continue through
this book up through inheritance (Chapter 6). But for completeness, here is a
brief description and example using <B>protected</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I56'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I57>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>protected</B> keyword deals with a
concept called <A NAME="Index511"></A><I>inheritance</I>, 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="Index512"></A><A NAME="Index513"></A><I>base</I> <I>class</I>. 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="Index514"></A><B>extends
</B>an existing class, like this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>class</font> Foo <font color=#0000ff>extends</font> Bar {</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The rest of the class definition looks
the same.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I57'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I58>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you create a new package and you
inherit from a class in another package, the only members you have access to are
the <B>public</B> members of the original package. (Of course, if you perform
the inheritance in the <I>same</I> 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 <B>protected</B> does. If you
refer back to the file <B>Cookie.java</B>, the following class <I>cannot</I>
access the “friendly” member:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c05: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(
<font color=#004488>"ChocolateChip constructor"</font>);
}
<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.bite(); // Can't access bite</font>
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">One of the interesting things about
inheritance is that if a method <B>bite( )</B> exists in class
<B>Cookie</B>, then it also exists in any class inherited from <B>Cookie</B>.
But since <B>bite( )</B> is “friendly” in a foreign package,
it’s unavailable to us in this one. Of course, you could make it
<B>public</B>, but then everyone would have access and maybe that’s not
what you want. If we change the class <B>Cookie</B> as follows:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>public</font> <font color=#0000ff>class</font> Cookie {
<font color=#0000ff>public</font> Cookie() {
System.out.println(<font color=#004488>"Cookie constructor"</font>);
}
<font color=#0000ff>protected</font> <font color=#0000ff>void</font> bite() {
System.out.println(<font color=#004488>"bite"</font>);
}
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">then <B>bite( )</B> still has
“friendly” access within package <B>dessert</B>, but it is also
accessible to anyone inheriting from <B>Cookie</B>. However, it is <I>not</I>
<A NAME="Index515"></A><B>public</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I58'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I59>
</FONT><A NAME="_Toc375545301"></A><A NAME="_Toc481064599"></A><BR></P></DIV>
<A NAME="Heading202"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Interface and implementation</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Access control is often referred to as
<I>implementation hiding<A NAME="Index516"></A><A NAME="Index517"></A></I>.
Wrapping data and methods within classes in combination with implementation
hiding is often called
<I>encapsulation</I></FONT><A NAME="fnB34" HREF="#fn34">[34]</A><A NAME="Index518"></A><FONT FACE="Geor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -