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

📄 tij0080.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 3 页
字号:
is a simple extension to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Monster</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that produces a new 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This is implemented in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DragonZilla</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
syntax used in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vampire</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
works 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>only</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
when inheriting interfaces. Normally, you can use <A NAME="Index605"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>extends</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
with only a single class, but since an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can be made from multiple other interfaces, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>extends</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
can refer to multiple base interfaces when building a new 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
As you can see, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
names are simply separated with commas.
</FONT><a name="_Toc408018541"></a><a name="_Toc375545338"></a><P></DIV>
<A NAME="Heading219"></A><H3 ALIGN=LEFT>
Grouping
constants
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Because
any fields you put into an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are automatically 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a convenient tool for <A NAME="Index606"></A><A NAME="Index607"></A>creating
groups of constant values, much as you would with an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>enum</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in C or C++. For example:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Months.java</font>
<font color="#009900">// Using interfaces to create groups of constants</font>
<font color="#0000ff">package</font> c07;

<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">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Notice
the Java style of using all uppercase letters (with underscores to separate
multiple words in a single identifier) for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
primitives that have constant initializers &#8211; that is, for compile-time
constants.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
fields in an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">are
automatically 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>public</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so it&#8217;s unnecessary to specify that.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Now
you can use the constants from outside the package by importing 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c07.*</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c07.Months</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
just as you would with any other package, and referencing the values with
expressions like 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Months.JANUARY</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Of course, what you get is just an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
so there isn&#8217;t the extra type safety that C++&#8217;s 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>enum</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has, but this (commonly-used) technique is certainly an improvement over
hard-coding numbers into your programs. (This is often referred to as using
&#8220;magic numbers&#8221; and it produces very difficult-to-maintain code.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">If
you do want extra type safety, you can build a class like this:
</FONT><A NAME="fnB28" HREF="#fn28">[28]</A><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Month2.java</font>
<font color="#009900">// A more robust enumeration system</font>
<font color="#0000ff">package</font> c07;

<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("January"), 
    FEB = <font color="#0000ff">new</font> Month2("February"),
    MAR = <font color="#0000ff">new</font> Month2("March"),
    APR = <font color="#0000ff">new</font> Month2("April"),
    MAY = <font color="#0000ff">new</font> Month2("May"),
    JUN = <font color="#0000ff">new</font> Month2("June"),
    JUL = <font color="#0000ff">new</font> Month2("July"),
    AUG = <font color="#0000ff">new</font> Month2("August"),
    SEP = <font color="#0000ff">new</font> Month2("September"),
    OCT = <font color="#0000ff">new</font> Month2("October"),
    NOV = <font color="#0000ff">new</font> Month2("November"),
    DEC = <font color="#0000ff">new</font> Month2("December");
  <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">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
class is called 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Month2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
since there&#8217;s already a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Month</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in the standard Java library. It&#8217;s a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class with a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor so no one can inherit from it or make any instances of it. The only
instances are the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final
static
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
ones created in the class itself: 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>JAN</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FEB</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>MAR</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
etc. These objects are also used in the array 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>month</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which lets you choose months by number instead of by name. (Notice the extra 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>JAN</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in the array to provide an offset by one, so that December is month 12.) 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">
you can see the <A NAME="Index608"></A>type
safety: 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>m</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Month2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object so it can be assigned only to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Month2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The previous example 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Months.java
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">provided
only 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
values, so an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>int</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
variable intended to represent a month could actually be given any integer
value, which wasn&#8217;t too safe.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">This
approach also allows you to use 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>==</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>equals(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
interchangeably, as shown at the end of 
</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="_Toc408018542"></a><P></DIV>
<A NAME="Heading220"></A><H3 ALIGN=LEFT>
Initializing
fields in interfaces
<P><A NAME="Index609"></A><A NAME="Index610"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Fields
defined in interfaces are automatically 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
These cannot be &#8220;blank finals,&#8221; but they can be initialized with
non-constant expressions. For example:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: 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">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Since
the fields are 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
they are initialized when the class is first loaded, upon first access of any
of the fields. Here&#8217;s a simple test:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: 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);
    System.out.println(RandVals.rfloat);
    System.out.println(RandVals.rdouble);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
fields, of course, are not part of the interface but instead are stored in the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
storage area for that interface.
</FONT><a name="_Toc408018543"></a><P></DIV>
<HR><DIV ALIGN=LEFT><A NAME="fn28" HREF="#fnB28">[28]</A><FONT FACE="Carmina Md BT" SIZE=2 COLOR="Black">
This approach was inspired by an e-mail from Rich Hoffarth.
</FONT><P></DIV>


<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0079.html">Prev</a> | <a href="tij0081.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

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