📄 tij0081.html
字号:
is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so no one but
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Parcel3</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
classes in the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Parcel3</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
package (since
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
also gives package access; that is,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is also “friendly”), and the inheritors of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Parcel3
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">can
access
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This means that the client programmer has restricted knowledge and access to
these members. In fact, you can’t even downcast to a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
inner class (or a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
inner class unless you’re an inheritor), because you can’t access
the name, as you can see in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>class
Test
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Thus, the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
inner class provides a way for the class designer to completely prevent any
type-coding dependencies and to completely hide details about implementation.
In addition, extension of an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is useless from the client programmer’s perspective since the client
programmer cannot access any additional methods that aren’t part of the
public
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class. This also provides an opportunity for the Java compiler to generate more
efficient code.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Normal
(non-inner) classes cannot be made
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>protected
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">–
only
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or “friendly.”
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Note
that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn’t need to be an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class. You could use an ordinary class here as well, but the most typical
starting point for such a design is an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><a name="_Toc408018545"></a><P></DIV>
<A NAME="Heading223"></A><H3 ALIGN=LEFT>
Inner
classes in methods and scopes
<P><A NAME="Index621"></A><A NAME="Index622"></A><A NAME="Index623"></A><A NAME="Index624"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">What
you’ve seen so far encompasses the typical use for inner classes. In
general, the code that you’ll write and read involving inner classes will
be “plain” inner classes that are simple and easy to understand.
However, the design for inner classes is quite complete and there are a number
of other, more obscure, ways that you can use them if you choose: inner classes
can be created within a method or even an arbitrary scope. There are two
reasons for doing this:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> As
shown previously, you’re implementing an interface of some kind so that
you can create and return a handle.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> You’re
solving a complicated problem and you want to create a class to aid in your
solution, but you don’t want it publicly available.
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
the following examples, the previous code will be modified to use:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> A
class defined within a method
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> A
class defined within a scope inside a method
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> An
<A NAME="Index625"></A><A NAME="Index626"></A>anonymous
class implementing an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> An
anonymous class extending a class that has a non-default constructor
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> An
anonymous class that performs field initialization
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"> An
anonymous class that performs <A NAME="Index627"></A>construction
using instance initialization (anonymous inner classes cannot have constructors)
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
will all take place within the package
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>innerscopes</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
First, the common interfaces from the previous code will be defined in their
own files so they can be used in all the examples:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Destination.java</font>
<font color="#0000ff">package</font> c07.innerscopes;
<font color="#0000ff">interface</font> Destination {
String readLabel();
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
point has been made that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
could be an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class, so here it will be in a more natural form, as an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Contents.java</font>
<font color="#0000ff">package</font> c07.innerscopes;
<font color="#0000ff">interface</font> Contents {
<font color="#0000ff">int</font> value();
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Although
it’s an ordinary class with an implementation,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Wrapping</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is also being used as a common “interface” to its derived classes:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Wrapping.java</font>
<font color="#0000ff">package</font> c07.innerscopes;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Wrapping {
<font color="#0000ff">private</font> <font color="#0000ff">int</font> i;
<font color="#0000ff">public</font> Wrapping(<font color="#0000ff">int</font> x) { i = x; }
<font color="#0000ff">public</font> <font color="#0000ff">int</font> value() { <font color="#0000ff">return</font> i; }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You’ll
notice above that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Wrapping</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has a constructor that requires an argument, to make things a bit more
interesting.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
first example shows the creation of an entire class within the scope of a
method (instead of the scope of another class):
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Parcel4.java</font>
<font color="#009900">// Nesting a class within a method</font>
<font color="#0000ff">package</font> c07.innerscopes;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Parcel4 {
<font color="#0000ff">public</font> Destination dest(String s) {
<font color="#0000ff">class</font> PDestination
<font color="#0000ff">implements</font> Destination {
<font color="#0000ff">private</font> String label;
<font color="#0000ff">private</font> PDestination(String whereTo) {
label = whereTo;
}
<font color="#0000ff">public</font> String readLabel() { <font color="#0000ff">return</font> label; }
}
<font color="#0000ff">return</font> <font color="#0000ff">new</font> PDestination(s);
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
Parcel4 p = <font color="#0000ff">new</font> Parcel4();
Destination d = p.dest("Tanzania");
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is part of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dest( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
rather than being part of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Parcel4.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(Also notice that you could use the class identifier
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">for
an inner class inside each class in the same subdirectory without a name
clash.) Therefore,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">cannot
be accessed outside of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dest( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Notice
the upcasting that occurs in the return statement – nothing comes out of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dest( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
except a handle to the base class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Destination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Of course, the fact that the name of the class
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is placed inside
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dest( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn’t mean that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is not a valid object once
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>dest( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
returns.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
next example shows how you can nest an <A NAME="Index628"></A><A NAME="Index629"></A><A NAME="Index630"></A>inner
class within any arbitrary scope:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Parcel5.java</font>
<font color="#009900">// Nesting a class within a scope</font>
<font color="#0000ff">package</font> c07.innerscopes;
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Parcel5 {
<font color="#0000ff">private</font> <font color="#0000ff">void</font> internalTracking(<font color="#0000ff">boolean</font> b) {
<font color="#0000ff">if</font>(b) {
<font color="#0000ff">class</font> TrackingSlip {
<font color="#0000ff">private</font> String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() { <font color="#0000ff">return</font> id; }
}
TrackingSlip ts = <font color="#0000ff">new</font> TrackingSlip("slip");
String s = ts.getSlip();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -