📄 tij307.htm
字号:
});
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>In a second file in the same directory:<br></p>
<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><p><br></p>
<p>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> have package access and therefore not available to <b>Cake</b>. They <i>do</i> have package access—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 thus they provide package access to all the other files in that directory. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_864" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc375545298"></a><a name="_Toc24775628"></a><a name="Heading4849"></a><b>private</b>:
you can’t touch that!</h3>
<p>The <b>private</b> keyword means that no one can access that member except the class that contains that member, inside methods of that class. Other classes in the same package cannot access <a name="Index451"></a><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. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_865" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The default package access often provides an adequate amount of hiding; remember, a package-access member is inaccessible to the client programmer using the class. 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 13.) <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_866" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Here’s an example of the use of <b>private</b>:<br></p>
<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><p><br></p>
<p>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 preceding example, 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.<sup><a name="fnB28" href="#fn28">[28]</a></sup> <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_867" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>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. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_868" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The same is true for a <b>private </b>field inside a class. Unless you must expose the underlying implementation (which is less likely 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.) <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_869" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc312373839"></a><a name="_Toc375545299"></a><a name="_Toc24775629"></a><a name="Heading4874"></a><b>protected</b>:
inheritance access</h3>
<p>Understanding the <b>protected</b> access specifier requires a jump ahead. 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 <a name="Index452"></a><b>protected</b>. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_870" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The <b>protected</b> keyword deals with a concept called <a name="Index453"></a><i>inheritance</i>, which takes an existing class—which we refer to as the <a name="Index454"></a><a name="Index455"></a><i>base</i> <i>class</i>—and adds new members to that class without touching the existing class. 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="Index456"></a><b>extends </b>an existing class, like this:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>class</font> Foo <font color=#0000ff>extends</font> Bar {</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The rest of the class definition looks the same. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_871" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>If you create a new package and 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 can manipulate all the members that have package access) 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. <b>protected</b> also gives package access—that is, other classes in the same package may access <b>protected</b> elements.<br></p>
<p>If you refer back to the file <b>Cookie.java</b>, the following class <i>cannot</i> call the package-access member <b>bite( )</b>:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c05:ChocolateChip.java</font>
<font color=#009900>// Can't use package-access member from another package.</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;
<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>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
<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>
monitor.expect(<font color=#0000ff>new</font> String[] {
<font color=#004488>"Cookie constructor"</font>,
<font color=#004488>"ChocolateChip constructor"</font>
});
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>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> has package access and is 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:<br></p>
<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><p><br></p>
<p>then <b>bite( )</b> still has the equivalent of package 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="Index457"></a><b>public</b>. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_872" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc375545301"></a><a name="_Toc24775630"></a><a name="Heading4913"></a>Interface
and implementation</h2>
<p>Access control is often referred to as <i>implementation hiding</i>. Wrapping data and methods within classes in combination with implementation hiding is often called <a name="Index458"></a><a name="Index459"></a><i>encapsulation</i><a name="Index460"></a>.<sup><a name="fnB29" href="#fn29">[29]</a></sup> The result is a data type with characteristics and behaviors. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_873" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Access control puts boundaries within a 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 accidentally treat the internals as part of the interface that they should be using. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_874" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>This feeds directly into the second reason, which is to separate the interface from the implementation. If the structure is used in a set of programs, but client programmers can’t do anything but send messages to the <a name="Index461"></a><a name="Index462"></a><a name="Index463"></a><b>public</b> interface, then you are free to change anything that’s <i>not</i> <b>public</b> (e.g., package access, <b>protected</b>, or <b>private</b>) without breaking client code. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_875" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>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 size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_876" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>In the original OOP language, Simula-67, the keyword <a name="Index464"></a><a name="Index465"></a><b>class</b> 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 size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_877" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index466"></a>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 size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap05_878" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>For clarity, you might prefer a style of creating classes that puts the <a name="Index467"></a><a name="Index468"></a><b>public</b> members at the beginning, followed by the <b>protected</b>, package access, 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-<b>public</b> members, which are part of the internal implementation:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>public</font> <font color=#0000ff>class</font> X {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -