📄 chapter07.html
字号:
<font color=#009900>// Abstract classes and methods</font>
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>abstract</font> <font color=#0000ff>class</font> Instrument4 {
<font color=#0000ff>int</font> i; <font color=#009900>// storage allocated for each</font>
<font color=#0000ff>public</font> <font color=#0000ff>abstract</font> <font color=#0000ff>void</font> play();
<font color=#0000ff>public</font> String what() {
<font color=#0000ff>return</font> <font color=#004488>"Instrument4"</font>;
}
<font color=#0000ff>public</font> <font color=#0000ff>abstract</font> <font color=#0000ff>void</font> adjust();
}
<font color=#0000ff>class</font> Wind4 <font color=#0000ff>extends</font> Instrument4 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Wind4.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Wind4"</font>; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {}
}
<font color=#0000ff>class</font> Percussion4 <font color=#0000ff>extends</font> Instrument4 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Percussion4.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Percussion4"</font>; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {}
}
<font color=#0000ff>class</font> Stringed4 <font color=#0000ff>extends</font> Instrument4 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Stringed4.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Stringed4"</font>; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {}
}
<font color=#0000ff>class</font> Brass4 <font color=#0000ff>extends</font> Wind4 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Brass4.play()"</font>);
}
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {
System.out.println(<font color=#004488>"Brass4.adjust()"</font>);
}
}
<font color=#0000ff>class</font> Woodwind4 <font color=#0000ff>extends</font> Wind4 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Woodwind4.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Woodwind4"</font>; }
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Music4 {
<font color=#009900>// Doesn't care about type, so new types</font>
<font color=#009900>// added to the system still work right:</font>
<font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Instrument4 i) {
<font color=#009900>// ...</font>
i.play();
}
<font color=#0000ff>static</font> <font color=#0000ff>void</font> tuneAll(Instrument4[] e) {
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < e.length; i++)
tune(e[i]);
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Instrument4[] orchestra = <font color=#0000ff>new</font> Instrument4[5];
<font color=#0000ff>int</font> i = 0;
<font color=#009900>// Upcasting during addition to the array:</font>
orchestra[i++] = <font color=#0000ff>new</font> Wind4();
orchestra[i++] = <font color=#0000ff>new</font> Percussion4();
orchestra[i++] = <font color=#0000ff>new</font> Stringed4();
orchestra[i++] = <font color=#0000ff>new</font> Brass4();
orchestra[i++] = <font color=#0000ff>new</font> Woodwind4();
tuneAll(orchestra);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see that there’s
really no change except in the base class.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It’s helpful to create
<B>abstract </B>classes and methods because they make the abstractness of a
class explicit and tell both the user and the compiler how it was intended to be
used.</FONT><A NAME="_Toc375545335"></A><A NAME="_Toc408018538"></A><BR></P></DIV>
<A NAME="Heading215"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Interfaces</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The
<A NAME="Index588"></A><B>interface</B> keyword takes the abstract<B>
</B>concept one step further. You could think of it as a “pure”
abstract<B> </B>class. It allows the creator to establish the form for a class:
method names, argument lists and return types, but no method bodies. An
<B>interface</B> can also contain data members of primitive types, but these are
implicitly <A NAME="Index589"></A><B>static</B> and
<A NAME="Index590"></A><B>final</B>. An <B>interface</B> provides only a form,
but no <A NAME="Index591"></A>implementation.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">An <B>interface</B> says:
“This is what all classes that <I>implement</I> this particular interface
will look like.” Thus, any code that uses a particular <B>interface</B>
knows what methods might be called for that <B>interface</B>, and that’s
all. So the <B>interface</B> is used to establish a “protocol”
between classes. (Some object-oriented programming languages have a keyword
called <A NAME="Index592"></A><A NAME="Index593"></A><I>protocol</I> to do the
same thing.)</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To create an <B>interface</B>, use
the <B>interface</B> keyword instead of the <B>class</B> keyword. Like a class,
you can add the <A NAME="Index594"></A><B>public</B> keyword before the
<B>interface </B>keyword (but only if that <B>interface</B> is defined in a file
of the same name) or leave it off to give
“<A NAME="Index595"></A>friendly” status.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To make a class that conforms to a
particular <B>interface</B> (or group of <B>interface</B>s) use the
<A NAME="Index596"></A><B>implements</B> keyword. You’re saying “The
<B>interface</B> is what it looks like and here’s how it
<I>works</I>.” Other than that, it bears a strong resemblance to
inheritance. The diagram for the instrument example shows this:</FONT><BR></P></DIV>
<DIV ALIGN="CENTER"><FONT FACE="Georgia"><IMG SRC="Tjava110.gif"></FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Once you’ve implemented an
<B>interface</B>, that implementation becomes an ordinary class that can be
extended in the regular way.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can choose to explicitly
declare the method declarations in an <B>interface</B> as <B>public</B>. But
they are <B>public</B> even if you don’t say it. So when you
<B>implement</B> an <B>interface</B>, the methods from the <B>interface</B> must
be defined as <B>public.</B> Otherwise they would default to
“friendly” and you’d be restricting the accessibility of a
method during inheritance, which is not allowed by the Java
compiler.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see this in the modified
version of the <B>Instrument</B> example. Note that every method in the
<B>interface</B> is strictly a declaration, which is the only thing the compiler
allows. In addition, none of the methods in <B>Instrument5</B> are declared as
<B>public</B>, but they’re automatically <B>public</B>
anyway:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Music5.java</font>
<font color=#009900>// Interfaces</font>
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>interface</font> Instrument5 {
<font color=#009900>// Compile-time constant:</font>
<font color=#0000ff>int</font> i = 5; <font color=#009900>// static & final</font>
<font color=#009900>// Cannot have method definitions:</font>
<font color=#0000ff>void</font> play(); <font color=#009900>// Automatically public</font>
String what();
<font color=#0000ff>void</font> adjust();
}
<font color=#0000ff>class</font> Wind5 <font color=#0000ff>implements</font> Instrument5 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Wind5.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Wind5"</font>; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {}
}
<font color=#0000ff>class</font> Percussion5 <font color=#0000ff>implements</font> Instrument5 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Percussion5.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Percussion5"</font>; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {}
}
<font color=#0000ff>class</font> Stringed5 <font color=#0000ff>implements</font> Instrument5 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Stringed5.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Stringed5"</font>; }
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {}
}
<font color=#0000ff>class</font> Brass5 <font color=#0000ff>extends</font> Wind5 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Brass5.play()"</font>);
}
<font color=#0000ff>public</font> <font color=#0000ff>void</font> adjust() {
System.out.println(<font color=#004488>"Brass5.adjust()"</font>);
}
}
<font color=#0000ff>class</font> Woodwind5 <font color=#0000ff>extends</font> Wind5 {
<font color=#0000ff>public</font> <font color=#0000ff>void</font> play() {
System.out.println(<font color=#004488>"Woodwind5.play()"</font>);
}
<font color=#0000ff>public</font> String what() { <font color=#0000ff>return</font> <font color=#004488>"Woodwind5"</font>; }
}
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Music5 {
<font color=#009900>// Doesn't care about type, so new types</font>
<font color=#009900>// added to the system still work right:</font>
<font color=#0000ff>static</font> <font color=#0000ff>void</font> tune(Instrument5 i) {
<font color=#009900>// ...</font>
i.play();
}
<font color=#0000ff>static</font> <font color=#0000ff>void</font> tuneAll(Instrument5[] e) {
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < e.length; i++)
tune(e[i]);
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Instrument5[] orchestra = <font color=#0000ff>new</font> Instrument5[5];
<font color=#0000ff>int</font> i = 0;
<font color=#009900>// Upcasting during addition to the array:</font>
orchestra[i++] = <font color=#0000ff>new</font> Wind5();
orchestra[i++] = <font color=#0000ff>new</font> Percussion5();
orchestra[i++] = <font color=#0000ff>new</font> Stringed5();
orchestra[i++] = <font color=#0000ff>new</font> Brass5();
orchestra[i++] = <font color=#0000ff>new</font> Woodwind5();
tuneAll(orchestra);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The rest of the code works the
same. It doesn’t matter if you are <A NAME="Index597"></A>upcasting to a
“regular” class called <B>Instrument5</B>, an <B>abstract</B> class
called <B>Instrument5</B>, or to an <A NAME="Index598"></A><B>interface</B>
called <B>Instrument5</B>. The behavior is the same. In fact, you can see in the
<B>tune( )</B> method that there isn’t any evidence about whether
<B>Instrument5</B> is a “regular” class, an <B>abstract</B> class or
an <B>interface</B>. This is the intent: Each approach gives the programmer
different control over the way objects are created and
used.</FONT><A NAME="_Toc375545336"></A><A NAME="_Toc408018539"></A><BR></P></DIV>
<A NAME="Heading216"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
“Multiple inheritance” in Java</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>interface</B> isn’t
simply a “more pure” form of <B>abstract</B> class. It has a higher
purpose than that. Because an <B>interface</B> has no implementation at all
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -