chapter05.html
来自「java 是一个很好的网络开发环境。由于它是通过解释的方法」· HTML 代码 · 共 1,008 行 · 第 1/5 页
HTML
1,008 行
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="fnB25" HREF="#fn25">[25]</A><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 you from changing or removing the method. Making a
method <B>private</B> guarantees that you retain this option. (However, just
because the handle is <B>private</B> doesn't mean that some other object can't
have a <B>public</B> 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><BR></P></DIV>
<A NAME="Heading174"></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="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 <B>protected</B>. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>protected</B> keyword deals
with a concept called <A NAME="Index394"></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="Index395"></A><A NAME="Index396"></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="Index397"></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.</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> on page 203, the following class
<I>cannot</I> access the “friendly” member:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><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(
<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.foo(); // Can't access foo</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>foo( )</B> exists in class
<B>Cookie</B>, then it also exists in any class inherited from <B>Cookie</B>.
But since <B>foo( )</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> foo() {
System.out.println(<font color=#004488>"foo"</font>);
}
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">then <B>foo( )</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>
<B>public</B>.</FONT><A NAME="_Toc375545301"></A><A NAME="_Toc408018504"></A><BR></P></DIV>
<A NAME="Heading175"></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="Index398"></A><A NAME="Index399"></A></I>.
Wrapping data and methods within classes (combined with implementation hiding
this is often called <I>encapsulation<A NAME="Index400"></A></I>) produces a
data type with characteristics and behaviors, but access control puts boundaries
within that data type for two important reasons. The first is to establish what
the client programmers can and can’t use. You can build your internal
mechanisms into the structure without worrying that the client programmers will
think it’s part of the interface that they should be
using.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This feeds directly into the second
reason, which is to separate the interface from the implementation.
<A NAME="Index401"></A><A NAME="Index402"></A><A NAME="Index403"></A> If the
structure is used in a set of programs, but users can’t do anything but
send messages to the <B>public</B> interface, then you can change anything
that’s <I>not</I> <B>public</B> (e.g. “friendly,”
<B>protected</B>, or <B>private</B>) without requiring modifications to their
code.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">We’re now in the world of
object-oriented programming, where a <B>class</B> is actually describing
“a class of objects,” as you would describe a class of fishes or a
class of birds. Any object belonging to this class will share these
characteristics and behaviors. The class is a description of the way all objects
of this type will look and act.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In the original OOP
<A NAME="Index404"></A>language, Simula-67<A NAME="Index405"></A>, the keyword
<B>class</B> <A NAME="Index406"></A>was used to describe a new data type. The
same keyword has been used for most object-oriented languages. This is the focal
point of the whole language: the creation of new data types that are more than
just boxes containing data and methods.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The class is the fundamental OOP
concept in Java. It is one of the keywords that will <I>not </I>be set in bold
in this book – it becomes annoying with a word repeated as often as
“class.”</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For clarity, you might prefer a
<A NAME="Index407"></A><A NAME="Index408"></A>style of creating classes that
puts the <B>public</B> members at the beginning, followed by the
<B>protected</B>, friendly and <B>private</B> members. The advantage is that the
user of the class can then read down from the top and see first what’s
important to them (the <B>public</B> members, because they can be accessed
outside the file) and stop reading when they encounter the non-public members,
which are part of the internal implementation. However, with the comment
documentation supported by javadoc (described in Chapter 2) the issue of code
readability by the client programmer becomes less important.</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>public</font> <font color=#0000ff>class</font> X {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> pub1( ) { <font color=#009900>/* . . . */</font> }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> pub2( ) { <font color=#009900>/* . . . */</font> }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> pub3( ) { <font color=#009900>/* . . . */</font> }
<font color=#0000ff>private</font> <font color=#0000ff>void</font> priv1( ) { <font color=#009900>/* . . . */</font> }
<font color=#0000ff>private</font> <font color=#0000ff>void</font> priv2( ) { <font color=#009900>/* . . . */</font> }
<font color=#0000ff>private</font> <font color=#0000ff>void</font> priv3( ) { <font color=#009900>/* . . . */</font> }
<font color=#0000ff>private</font> <font color=#0000ff>int</font> i;
<font color=#009900>// . . .</font>
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This will make it only partially
easier to read because the interface and implementation are still mixed
together. That is, you still see the source code – the implementation
– because it’s right there in the class. Displaying the interface to
the consumer of a class is really the job of the
<A NAME="Index409"></A><A NAME="Index410"></A><I>class browser</I>, a tool whose
job is to look at all the available classes and show you what you can do with
them (i.e. what members are available) in a useful fashion. By the time you read
this, good browsers should be an expected part of any good Java development
tool.</FONT><A NAME="_Toc312373850"></A><A NAME="_Toc375545302"></A><A NAME="_Toc408018505"></A><BR></P></DIV>
<A NAME="Heading176"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Class access<BR><A NAME="Index411"></A><A NAME="Index412"></A></H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In Java, the access specifiers can
also be used to determine which classes <I>within</I> a library will be
available to the users of that library. If you want a class to be available to a
client programmer, you place the <B>public</B> keyword somewhere before the
opening brace of the class body. This controls whether the client programmer can
even create an object of the class. </FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To control the access of a class,
the specifier must appear before the keyword <B>class</B>.<B> </B>Thus you can
say:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>public</font> <font color=#0000ff>class</font> Widget {</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">That is, if the name of your
library is <B>mylib</B> any client programmer can access <B>Widget</B> by
saying</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>import</font> mylib.Widget;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">or</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>import</font> mylib.*;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">However, there’s an extra
pair of constraints:</FONT><BR></P></DIV>
<OL>
<LI><FONT FACE="Georgia"> There can be only one <B>public</B> class per
compilation unit (file). The idea is that each compilation unit has a single
public interface represented by that public class. It can have as many
supporting “friendly” classes as you want. If you have more than one
<B>public</B> class inside a compilation unit, the compiler will give you an
error message.</FONT><LI><FONT FACE="Georgia"> The name of the
<B>public</B> class must exactly match the name of the file containing the
compilation unit, including capitalization. So for <B>Widget</B>, the name of
the file must be <B>Widget.java</B>, not <B>widget.java</B> or
<B>WIDGET.java</B>. Again, you’ll get a compile-time error if they
don’t agree.</FONT><LI><FONT FACE="Georgia"> It is possible, though
not typical, to have a compilation unit with no public class at all. In this
case, you can name the file whatever you
like.</FONT></OL><DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What if
you’ve got a class inside <B>mylib</B> that you’re just using to
accomplish the tasks performed by <B>Widget</B> or some other <B>public</B>
class in <B>mylib</B>? You don’t want to go to the bother of creating
documentation for the client programmer, and you think that sometime later you
might want to completely change things and rip out your class altogether,
substituting a different one. To give you this flexibility, you need to ensure
that no client programmers become dependent on your particular implementation
details hidden inside <B>mylib</B>. To accomplish this, you just leave the
<B>public</B> keyword off the class, in which case it becomes friendly. (That
class can be used only within that package.)</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that a class cannot be
<B>private </B>(that would make it accessible to no one but the class), or
<B>protected</B>.</FONT><A NAME="fnB26" HREF="#fn26">[26]</A><FONT FACE="Georgia">
So you have only two choices for
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?