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

📄 chap08.htm

📁 Thinking in Java, 2nd edition
💻 HTM
📖 第 1 页 / 共 5 页
字号:

<font color=#0000ff>class</font> DragonZilla <font color=#0000ff>implements</font> DangerousMonster {
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> menace() {}
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> destroy() {}
}

<font color=#0000ff>interface</font> Vampire 
    <font color=#0000ff>extends</font> DangerousMonster, Lethal {
  <font color=#0000ff>void</font> drinkBlood();
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> HorrorShow {
  <font color=#0000ff>static</font> <font color=#0000ff>void</font> u(Monster b) { b.menace(); }
  <font color=#0000ff>static</font> <font color=#0000ff>void</font> v(DangerousMonster d) {
    d.menace();
    d.destroy();
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    DragonZilla if2 = <font color=#0000ff>new</font> DragonZilla();
    u(if2);
    v(if2);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>DangerousMonster</B> is a simple
extension to <B>Monster</B> that produces a new <B>interface</B>. This is
implemented in <B>DragonZilla</B>.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I15' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I16>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The syntax used in <B>Vampire</B> works
<I>only</I> when inheriting interfaces. Normally, you can use
<A NAME="Index771"></A><B>extends</B> with only a single class, but since an
<B>interface</B> can be made from multiple other interfaces, <B>extends</B> can
refer to multiple base interfaces when building a new <B>interface</B>. As you
can see, the <B>interface</B> names are simply separated with commas.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I16' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I17>
</FONT><A NAME="_Toc481064646"></A><BR></P></DIV>
<A NAME="Heading257"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Grouping constants</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Because any fields you put into an
<B>interface</B> are automatically <B>static</B> and <B>final</B>, the
<B>interface</B> is a convenient tool for
<A NAME="Index772"></A><A NAME="Index773"></A>creating groups of constant
values, much as you would with an <B>enum</B> in C or C++. For
example:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c08:Months.java</font>
<font color=#009900>// Using interfaces to create groups of constants.</font>
<font color=#0000ff>package</font> c08;

<font color=#0000ff>public</font> <font color=#0000ff>interface</font> Months {
  <font color=#0000ff>int</font>
    JANUARY = 1, FEBRUARY = 2, MARCH = 3, 
    APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, 
    AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10,
    NOVEMBER = 11, DECEMBER = 12;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice the Java style of using all
uppercase letters (with underscores to separate multiple words in a single
identifier) for <B>static</B> <B>final</B>s that have constant initializers.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I17' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I18>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The fields in an <B>interface </B>are
automatically <B>public</B>, so it&#8217;s unnecessary to specify that.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I18' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I19>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Now you can use the constants from
outside the package by importing <B>c08.*</B> or <B>c08.Months</B> just as you
would with any other package, and referencing the values with expressions like
<B>Months.JANUARY</B>. Of course, what you get is just an <B>int</B>, so there
isn&#8217;t the extra type safety that C++&#8217;s <B>enum</B> has, but this
(commonly used) technique is certainly an improvement over hard-coding numbers
into your programs. (That approach is often referred to as using &#8220;magic
numbers&#8221; and it produces very difficult-to-maintain code.)

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I19' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I20>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you do want extra type safety, you can
build a class like
this</FONT><A NAME="fnB38" HREF="#fn38">[38]</A><FONT FACE="Georgia">:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c08:Month2.java</font>
<font color=#009900>// A more robust enumeration system.</font>
<font color=#0000ff>package</font> c08;

<font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>class</font> Month2 {
  <font color=#0000ff>private</font> String name;
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> order;
  <font color=#0000ff>private</font> Month2(<font color=#0000ff>int</font> ord, String nm) { 
    order = ord; 
    name = nm; 
  }
  <font color=#0000ff>public</font> String toString() { <font color=#0000ff>return</font> name; }
  <font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> Month2
    JAN = <font color=#0000ff>new</font> Month2(1, <font color=#004488>"January"</font>), 
    FEB = <font color=#0000ff>new</font> Month2(2, <font color=#004488>"February"</font>),
    MAR = <font color=#0000ff>new</font> Month2(3, <font color=#004488>"March"</font>),
    APR = <font color=#0000ff>new</font> Month2(4, <font color=#004488>"April"</font>),
    MAY = <font color=#0000ff>new</font> Month2(5, <font color=#004488>"May"</font>),
    JUN = <font color=#0000ff>new</font> Month2(6, <font color=#004488>"June"</font>),
    JUL = <font color=#0000ff>new</font> Month2(7, <font color=#004488>"July"</font>),
    AUG = <font color=#0000ff>new</font> Month2(8, <font color=#004488>"August"</font>),
    SEP = <font color=#0000ff>new</font> Month2(9, <font color=#004488>"September"</font>),
    OCT = <font color=#0000ff>new</font> Month2(10, <font color=#004488>"October"</font>),
    NOV = <font color=#0000ff>new</font> Month2(11, <font color=#004488>"November"</font>),
    DEC = <font color=#0000ff>new</font> Month2(12, <font color=#004488>"December"</font>);
  <font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> Month2[] month =  {
    JAN, FEB, MAR, APR, MAY, JUN,
    JUL, AUG, SEP, OCT, NOV, DEC
  };
  <font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> Month2 number(<font color=#0000ff>int</font> ord) {
    <font color=#0000ff>return</font> month[ord - 1];
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Month2 m = Month2.JAN;
    System.out.println(m);
    m = Month2.number(12);
    System.out.println(m);
    System.out.println(m == Month2.DEC);
    System.out.println(m.equals(Month2.DEC));
  }
} <font color=#009900>///:~//: c08:Month2.java</font>
<font color=#009900>// A more robust enumeration system.</font>
<font color=#0000ff>package</font> c08;

<font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>class</font> Month2 {
  <font color=#0000ff>private</font> String name;
  <font color=#0000ff>private</font> Month2(String nm) { name = nm; }
  <font color=#0000ff>public</font> String toString() { <font color=#0000ff>return</font> name; }
  <font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> Month2
    JAN = <font color=#0000ff>new</font> Month2(<font color=#004488>"January"</font>), 
    FEB = <font color=#0000ff>new</font> Month2(<font color=#004488>"February"</font>),
    MAR = <font color=#0000ff>new</font> Month2(<font color=#004488>"March"</font>),
    APR = <font color=#0000ff>new</font> Month2(<font color=#004488>"April"</font>),
    MAY = <font color=#0000ff>new</font> Month2(<font color=#004488>"May"</font>),
    JUN = <font color=#0000ff>new</font> Month2(<font color=#004488>"June"</font>),
    JUL = <font color=#0000ff>new</font> Month2(<font color=#004488>"July"</font>),
    AUG = <font color=#0000ff>new</font> Month2(<font color=#004488>"August"</font>),
    SEP = <font color=#0000ff>new</font> Month2(<font color=#004488>"September"</font>),
    OCT = <font color=#0000ff>new</font> Month2(<font color=#004488>"October"</font>),
    NOV = <font color=#0000ff>new</font> Month2(<font color=#004488>"November"</font>),
    DEC = <font color=#0000ff>new</font> Month2(<font color=#004488>"December"</font>);
  <font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> Month2[] month =  {
    JAN, JAN, FEB, MAR, APR, MAY, JUN,
    JUL, AUG, SEP, OCT, NOV, DEC
  };
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Month2 m = Month2.JAN;
    System.out.println(m);
    m = Month2.month[12];
    System.out.println(m);
    System.out.println(m == Month2.DEC);
    System.out.println(m.equals(Month2.DEC));
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The class is called <B>Month2</B>, since
there&#8217;s already a <B>Month</B> in the standard Java library. It&#8217;s a
<B>final</B> class with a <B>private</B> constructor so no one can inherit from
it or make any instances of it. The only instances are the <B>final static</B>
ones created in the class itself: <B>JAN</B>, <B>FEB</B>, <B>MAR</B>, etc. These
objects are also used in the array <B>month</B>, which lets you <STRIKE>choose
months by number instead of by name. (Notice the extra <B>JAN</B> in the array
to provide an offset by one, so that December is month 12.)</STRIKE><U>iterate
through an array of <B>Month2</B> objects.</U> <U>The <B>number( ) </B>method
allows you to select a <B>Month2 </B>by giving its corresponding month number.
</U>In <B>main(&#160;)</B> you can see the <A NAME="Index774"></A>type safety:
<B>m</B> is a <B>Month2</B> object so it can be assigned only to a
<B>Month2</B>. The previous example <B>Months.java </B>provided only <B>int</B>
values, so an <B>int</B> variable intended to represent a month could actually
be given any integer value, which wasn&#8217;t very safe.

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I20' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I21>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This approach also allows you to use
<B>==</B> or <B>equals(&#160;)</B> interchangeably, as shown at the end of
<B>main(&#160;)</B>.<U> This works because there can be only one instance of
each value of <B>Month2</B>.</U>

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I21' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I22>
</FONT><A NAME="_Toc481064647"></A><BR></P></DIV>
<A NAME="Heading258"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Initializing fields in
interfaces<BR><A NAME="Index775"></A><A NAME="Index776"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Fields defined in interfaces are
automatically <B>static</B> and <B>final</B>. These cannot be &#8220;blank
finals,&#8221; but they can be initialized with nonconstant expressions. For
example:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c08:RandVals.java</font>
<font color=#009900>// Initializing interface fields with </font>
<font color=#009900>// non-constant initializers.</font>
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>public</font> <font color=#0000ff>interface</font> RandVals {
  <font color=#0000ff>int</font> rint = (<font color=#0000ff>int</font>)(Math.random() * 10);
  <font color=#0000ff>long</font> rlong = (<font color=#0000ff>long</font>)(Math.random() * 10);
  <font color=#0000ff>float</font> rfloat = (<font color=#0000ff>float</font>)(Math.random() * 10);
  <font color=#0000ff>double</font> rdouble = Math.random() * 10;
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Since the fields are <B>static</B>, they
are initialized when the class is first loaded, which happens when any of the
fields are accessed for the first time. Here&#8217;s a simple test:

</backtalk:display>
[&nbsp;<a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER8_I22' 
  target="_blank">Add&nbsp;Comment</a>&nbsp;]

<backtalk:display ID=TIJ3_CHAPTER8_I23>
</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c08:TestRandVals.java</font>

<font color=#0000ff>public</font> <font color=#0000ff>class</font> TestRandVals {
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    System.out.println(RandVals.rint);
    System.out.println(RandVals.rlong);

⌨️ 快捷键说明

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