📄 tij0080.html
字号:
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 – 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’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’t the extra type safety that C++’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
“magic numbers” 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’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’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( )</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’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( )</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( )</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 “blank finals,” 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’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 + -