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

📄 tij0081.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<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="tij0080.html">Prev</a> | <a href="tij0082.html">Next</a>
</td>
</tr></table>
<hr>

<H2 ALIGN=LEFT>
Inner
classes
</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
Java 1.1<A NAME="Index611"></A>
it&#8217;s possible to place a class definition within another class
definition. This is called an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>inner
class
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The <A NAME="Index612"></A><A NAME="Index613"></A>inner
class is a useful feature because it allows you to group classes that logically
belong together and to control the visibility of one within the other. However,
it&#8217;s important to understand that inner classes are distinctly different
from composition.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Often,
while you're learning about them, the need for inner classes isn&#8217;t
immediately obvious. At the end of this section, after all of the syntax and
semantics of inner classes have been described, you&#8217;ll find an example
that should make clear the benefits of inner classes.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
create an inner class just as you&#8217;d expect: by placing the class
definition inside a surrounding class: (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">//: Parcel1.java</font>
<font color="#009900">// Creating inner classes</font>
<font color="#0000ff">package</font> c07.parcel1;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Parcel1 {
  <font color="#0000ff">class</font> Contents {
    <font color="#0000ff">private</font> <font color="#0000ff">int</font> i = 11;
    <font color="#0000ff">public</font> <font color="#0000ff">int</font> value() { <font color="#0000ff">return</font> i; }
  }
  <font color="#0000ff">class</font> Destination {
    <font color="#0000ff">private</font> String label;
    Destination(String whereTo) {
      label = whereTo;
    }
    String readLabel() { <font color="#0000ff">return</font> label; }
  }
  <font color="#009900">// Using inner classes looks just like</font>
  <font color="#009900">// using any other class, within Parcel1:</font>
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> ship(String dest) {
    Contents c = <font color="#0000ff">new</font> Contents();
    Destination d = <font color="#0000ff">new</font> Destination(dest);
  }  
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Parcel1 p = <font color="#0000ff">new</font> Parcel1();
    p.ship("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
inner classes, when used inside 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ship(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
look just like the use of any other classes. Here, the only practical
difference is that the names are nested within 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Parcel1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
You&#8217;ll see in a while that this isn&#8217;t the only difference.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">More
typically, an outer class will have a method that returns a handle to an inner
class, like this:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Parcel2.java</font>
<font color="#009900">// Returning a handle to an inner class</font>
<font color="#0000ff">package</font> c07.parcel2;

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Parcel2 {
  <font color="#0000ff">class</font> Contents {
    <font color="#0000ff">private</font> <font color="#0000ff">int</font> i = 11;
    <font color="#0000ff">public</font> <font color="#0000ff">int</font> value() { <font color="#0000ff">return</font> i; }
  }
  <font color="#0000ff">class</font> Destination {
    <font color="#0000ff">private</font> String label;
    Destination(String whereTo) {
      label = whereTo;
    }
    String readLabel() { <font color="#0000ff">return</font> label; }
  }
  <font color="#0000ff">public</font> Destination to(String s) {
    <font color="#0000ff">return</font> <font color="#0000ff">new</font> Destination(s);
  }
  <font color="#0000ff">public</font> Contents cont() { 
    <font color="#0000ff">return</font> <font color="#0000ff">new</font> Contents(); 
  }
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> ship(String dest) {
    Contents c = cont();
    Destination d = to(dest);
  }  
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Parcel2 p = <font color="#0000ff">new</font> Parcel2();
    p.ship("Tanzania");
    Parcel2 q = <font color="#0000ff">new</font> Parcel2();
    <font color="#009900">// Defining handles to inner classes:</font>
    Parcel2.Contents c = q.cont();
    Parcel2.Destination d = q.to("Borneo");
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you want to make an object of the inner class anywhere except from within a non-
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method of the outer class, you must specify the type of that object as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>OuterClassName.InnerClassName</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
as seen in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><a name="_Toc408018544"></a><P></DIV>
<A NAME="Heading222"></A><H3 ALIGN=LEFT>
Inner
classes and upcasting
<P><A NAME="Index614"></A><A NAME="Index615"></A><A NAME="Index616"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">So
far, inner classes don&#8217;t seem that dramatic. After all, if it&#8217;s
hiding you&#8217;re after, Java already has a perfectly good hiding mechanism
&#8211; just allow the class to be &#8220;<A NAME="Index617"></A>friendly&#8221;
(visible only within a <A NAME="Index618"></A><A NAME="Index619"></A>package)
rather than creating it as an inner class.
</FONT><P></DIV><DIV ALIGN=LEFT><A NAME="Index620"></A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">However,
inner classes really come into their own when you start upcasting to a base
class, and in particular to an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(The effect of producing an interface handle from an object that implements it
is essentially the same as upcasting to a base class.) That&#8217;s because the
inner class can then be completely unseen and unavailable to anyone, which is
convenient for hiding the implementation. All you get back is a handle to the
base class or the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface,</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and it&#8217;s possible that you can&#8217;t even find out the exact type, as
shown here:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Parcel3.java</font>
<font color="#009900">// Returning a handle to an inner class</font>
<font color="#0000ff">package</font> c07.parcel3;

<font color="#0000ff">abstract</font> <font color="#0000ff">class</font> Contents {
  <font color="#0000ff">abstract</font> <font color="#0000ff">public</font> <font color="#0000ff">int</font> value();
}

<font color="#0000ff">interface</font> Destination {
  String readLabel();
}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Parcel3 {
  <font color="#0000ff">private</font> <font color="#0000ff">class</font> PContents <font color="#0000ff">extends</font> Contents {
    <font color="#0000ff">private</font> <font color="#0000ff">int</font> i = 11;
    <font color="#0000ff">public</font> <font color="#0000ff">int</font> value() { <font color="#0000ff">return</font> i; }
  }
  <font color="#0000ff">protected</font> <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">public</font> Destination dest(String s) {
    <font color="#0000ff">return</font> <font color="#0000ff">new</font> PDestination(s);
  }
  <font color="#0000ff">public</font> Contents cont() { 
    <font color="#0000ff">return</font> <font color="#0000ff">new</font> PContents(); 
  }
}

<font color="#0000ff">class</font> Test {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Parcel3 p = <font color="#0000ff">new</font> Parcel3();
    Contents c = p.cont();
    Destination d = p.dest("Tanzania");
    <font color="#009900">// Illegal -- can't access private class:</font>
    <font color="#009900">//! Parcel3.PContents c = p.new PContents();</font>
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Destination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
represent interfaces available to the client programmer. (The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
remember, automatically makes all of its members 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">)
For convenience, these are placed inside a single file, but ordinarily 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Contents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Destination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
would each be 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">in
their own files.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Parcel3</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
something new has been added: the inner class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PContents</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private
</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">
can access it. 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PDestination</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -