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

📄 chap05.htm

📁 Thinking in Java, 2nd edition
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<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&#8217;ll look more at the concept of a <B>public</B> class later.) However,
the <B>bite(&#160;)</B> member is inaccessible inside <B>Dinner.java</B> since
<B>bite(&#160;)</B> is friendly only within package <B>dessert</B>.

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

<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(&#160;)</B> method! (Note that you must have
&#8216;.&#8217; in your CLASSPATH in order for the files to compile.)
You&#8217;d typically think that <B>Pie</B> and <B>f(&#160;)</B> are friendly
and therefore not available to <B>Cake</B>. They <I>are</I> friendly&#8212;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 &#8220;default package&#8221;
for that directory, and therefore friendly to all the other files in that
directory.

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

<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&#8217;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&#8217;s as if you&#8217;re
even insulating the class against yourself. On the other hand, it&#8217;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>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I51' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER5_I52>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The default &#8220;friendly&#8221;
package access often provides an adequate amount of hiding; remember, a
&#8220;friendly&#8221; 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&#8217;ll get if you forget to add any access control). Thus,
you&#8217;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&#8217;ll use the <B>private </B>keyword often
since it&#8217;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&#8217;ll
see in Chapter 14.) 
</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I52' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER5_I53>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;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(&#160;)</B> method to
do it for you</FONT><A NAME="fnB33" HREF="#fn33">[33]</A><FONT FACE="Georgia">.

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

<backtalk:display ID=TIJ3_CHAPTER5_I54>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Any method that you&#8217;re certain is
only a &#8220;helper&#8221; method for that class can be made <B>private,</B> to
ensure that you don&#8217;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>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I54' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<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>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I55' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<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: &#8220;sort of friendly&#8221;</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&#8217;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>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I56' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<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>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I57' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<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 &#8220;friendly&#8221; 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&#8217;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 &#8220;friendly&#8221; 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(&#160;)</B> exists in class
<B>Cookie</B>, then it also exists in any class inherited from <B>Cookie</B>.
But since <B>bite(&#160;)</B> is &#8220;friendly&#8221; in a foreign package,
it&#8217;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&#8217;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(&#160;)</B> still has
&#8220;friendly&#8221; 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>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I58' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<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 + -