📄 tij0058.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0057.html">Prev</a> | <a href="tij0059.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
Java
access specifiers
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
Java <A NAME="Index379"></A><A NAME="Index380"></A>access
specifiers <A NAME="Index381"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
<A NAME="Index382"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and <A NAME="Index383"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are placed in front of each definition for each member in your class, whether
it’s a data member or a method. Each access specifier controls the access
for only that particular definition. This is a distinct contrast to C++, in
which the access specifier controls all the definitions following it until
another access specifier comes along.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">One
way or another, everything has some kind of access specified for it. In the
following sections, you’ll learn all about the various types of access,
starting with the default access.
</FONT><a name="_Toc312373840"></a><a name="_Toc375545296"></a><a name="_Toc408018500"></a><P></DIV>
<A NAME="Heading171"></A><H3 ALIGN=LEFT>
“Friendly”</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">What
if you give no access specifier at all, as in all the examples before this
chapter? The default access has no keyword, but it is commonly referred to as
“friendly.” It means that all the other classes in the current
package have access to the friendly member, but to all the classes outside of
this package the member appears to be private. Since a compilation unit –
a file – can belong only to a single package, all the classes within a
single compilation unit are automatically friendly with each other. Thus,
friendly elements are also said to have <A NAME="Index384"></A><A NAME="Index385"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>package
access
</I></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">Friendly
access allows you to group related classes together in a package so that they
can easily interact with each other. When you put classes together in a package
(thus granting mutual access to their friendly members; e.g. making them
“friends”) you “own” the code in that package. It makes
sense that only code that you own should have friendly access to other code
that you own. You could say that friendly access gives a meaning or a reason
for grouping classes together in a package. In many languages the way you
organize your definitions in files can be willy-nilly, but in Java you’re
compelled to <A NAME="Index386"></A><A NAME="Index387"></A>organize
them in a sensible fashion. In addition, you’ll probably want to exclude
classes that shouldn’t have access to the classes being defined in the
current package.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">An
important question in any relationship is “Who can access my
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
implementation?” The class controls which code has access to its members.
There’s no magic way to “break in;” someone in another
package can’t declare a new class and say, “Hi, I’m a friend
of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Bob</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">’s!”
and expect to see the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
friendly, and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
members of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Bob</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The only way to grant access to a member is to:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Make
the member
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Then everybody, everywhere, can access it.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Make
the member friendly by leaving off any access specifier, and put the other
classes in the same package. Then the other classes can access the member.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> As
you’ll see in a later chapter where inheritance is introduced, an
inherited class can access a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
member as well as a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
member (but not
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
members). It can access friendly members only if the two classes are in the
same package. But don’t worry about that now.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> Provide
“accessor/mutator” methods (also known as “get/set”
methods) that read and change the value. This is the most civilized approach in
terms of OOP, and it is fundamental to Java Beans, as you’ll see in
Chapter 13.
</FONT><a name="_Ref351419800"></a><a name="_Toc375545297"></a><a name="_Toc408018501"></a></OL><A NAME="Heading172"></A><H3 ALIGN=LEFT>
public:
interface access
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you use the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword, it <A NAME="Index388"></A>means
that the member declaration that immediately follows
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is available to everyone, in particular to the client programmer who uses the
library. Suppose you define a package
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dessert</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
containing the following compilation unit: (See page
<A HREF=" PAGE#Running_programs">97</A>
if you have trouble executing this program.)
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Cookie.java</font>
<font color="#009900">// Creates a library</font>
<font color="#0000ff">package</font> c05.dessert;
<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">void</font> foo() { System.out.println("foo"); }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Remember,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
must reside in a subdirectory called
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dessert</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
in a directory under
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>C05
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">(indicating
Chapter 5 of this book) that must be under one of the CLASSPATH directories.
Don’t make the mistake of thinking that Java will always look at the
current directory as one of the starting points for searching. If you
don’t have a ‘
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">’
as one of the paths in your CLASSPATH, Java won’t look there.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
if you create a program that uses
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Dinner.java</font>
<font color="#009900">// Uses the library</font>
<font color="#0000ff">import</font> c05.dessert.*;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Dinner {
<font color="#0000ff">public</font> Dinner() {
System.out.println("Dinner constructor");
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
Cookie x = <font color="#0000ff">new</font> Cookie();
<font color="#009900">//! x.foo(); // Can't access</font>
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can create a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cookie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object, since its constructor is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and the class is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
(We’ll look more at the concept of a public class later.) However, the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>foo( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
member is inaccessible inside
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Dinner.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
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 only 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">.</FONT><P></DIV>
<A NAME="Heading173"></A><H4 ALIGN=LEFT>
The
default package
<P><A NAME="Index389"></A><A NAME="Index390"></A><A NAME="Index391"></A></H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
might be surprised to discover that the following code compiles, even though it
would appear that it breaks the rules:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Cake.java</font>
<font color="#009900">// Accesses a class in a separate </font>
<font color="#009900">// 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">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
a second file, in the same directory:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: 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("Pie.f()"); }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
might initially view these as completely foreign files, and yet
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Cake</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is able to create a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Pie</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object and call its
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -