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

📄 tij0080.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 3 页
字号:
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">there&#8217;s
nothing to prevent many 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
from being combined. This is valuable because there are times when you need to
say &#8220;An 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>x</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>a</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>and</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>b</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>and</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>c</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.&#8221;
In C++, this act of combining multiple class interfaces is called <A NAME="Index599"></A><A NAME="Index600"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>multiple
inheritance
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and it carries some rather sticky baggage because each class can have an
implementation. In Java, you can perform the same act, but only one of the
classes can have an implementation, so the problems seen in C++ do not occur
with Java when combining multiple interfaces:
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
a derived class, you aren&#8217;t forced to have a base class that is either an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or &#8220;concrete&#8221; (one with no 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods). If you 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>do</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
inherit from a non-
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">you
can inherit from only one. All the rest of the base elements must be 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s.
You place all the interface names after the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>implements
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">keyword
and separate them with commas. You can have as many 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
as you want and each one becomes an independent type that you can upcast to.
The following example shows a concrete class combined with several 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
to produce a new class:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Adventure.java</font>
<font color="#009900">// Multiple interfaces</font>
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">interface</font> CanFight {
  <font color="#0000ff">void</font> fight();
}

<font color="#0000ff">interface</font> CanSwim {
  <font color="#0000ff">void</font> swim();
}

<font color="#0000ff">interface</font> CanFly {
  <font color="#0000ff">void</font> fly();
}

<font color="#0000ff">class</font> ActionCharacter {
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> fight() {}
}

<font color="#0000ff">class</font> Hero <font color="#0000ff">extends</font> ActionCharacter 
    <font color="#0000ff">implements</font> CanFight, CanSwim, CanFly {
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> swim() {}
  <font color="#0000ff">public</font> <font color="#0000ff">void</font> fly() {}
}

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Adventure {
  <font color="#0000ff">static</font> <font color="#0000ff">void</font> t(CanFight x) { x.fight(); }
  <font color="#0000ff">static</font> <font color="#0000ff">void</font> u(CanSwim x) { x.swim(); }
  <font color="#0000ff">static</font> <font color="#0000ff">void</font> v(CanFly x) { x.fly(); }
  <font color="#0000ff">static</font> <font color="#0000ff">void</font> w(ActionCharacter x) { x.fight(); }
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Hero i = <font color="#0000ff">new</font> Hero();
    t(i); <font color="#009900">// Treat it as a CanFight</font>
    u(i); <font color="#009900">// Treat it as a CanSwim</font>
    v(i); <font color="#009900">// Treat it as a CanFly</font>
    w(i); <font color="#009900">// Treat it as an ActionCharacter</font>
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hero</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
combines the concrete class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ActionCharacter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
with the interfaces 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CanFight</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CanSwim</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>CanFly</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
When you combine a concrete class with interfaces this way, the concrete class
must come first, then the interfaces. (The compiler gives an error otherwise.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Note
that the signature for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fight(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is the same in the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface
CanFight
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and the class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ActionCharacter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fight(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
provided with a definition in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hero</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The rule for an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is that you can inherit from it (as you will see shortly), but then
you&#8217;ve got another 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
If you want to create an object of the new type, it must be a class with all
definitions provided. Even though 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hero</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
does not explicitly provide a definition for 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fight(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
the definition comes along with 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ActionCharacter</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
so it is automatically provided and it&#8217;s possible to create objects of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hero</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">In
class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Adventure</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
you can see that there are four methods that take as arguments the various
interfaces and the concrete class. When a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hero</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object is created, it can be passed to any of these methods, which means it is
being upcast to each 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in turn. Because of the way interfaces are designed in Java, this works without
a hitch and without any particular effort on the part of the programmer.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Keep
in mind that the core reason for interfaces is shown in the above example: to
be able to upcast to more than one base type. However, a second reason for
using interfaces is the same as using an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">base
class: to prevent the client programmer from making an object of this class and
to establish that it is only an interface. This brings up a question: Should
you use an <A NAME="Index601"></A><A NAME="Index602"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class? An 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
gives you the benefits of an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>and</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
the benefits of an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so if it&#8217;s possible to create your base class without any method
definitions or member variables you should always prefer 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
classes. In fact, if you know something is going to be a base class, your first
choice should be to make it an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and only if you&#8217;re forced to have method definitions or member variables
should you change to an 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>abstract</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class.
</FONT><a name="_Toc375545337"></a><a name="_Toc408018540"></a><P></DIV>
<A NAME="Heading218"></A><H3 ALIGN=LEFT>
Extending
an interface 
<P>with
inheritance
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can easily add new method declarations to an <A NAME="Index603"></A><A NAME="Index604"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
using inheritance, and you can also combine several 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>interface</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
into 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">
with inheritance. In both cases you get 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 seen in this example:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: HorrorShow.java</font>
<font color="#009900">// Extending an interface with inheritance</font>

<font color="#0000ff">interface</font> Monster {
  <font color="#0000ff">void</font> menace();
}

<font color="#0000ff">interface</font> DangerousMonster <font color="#0000ff">extends</font> Monster {
  <font color="#0000ff">void</font> destroy();
}

<font color="#0000ff">interface</font> Lethal {
  <font color="#0000ff">void</font> kill();
}

<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">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">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>DangerousMonster</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">

⌨️ 快捷键说明

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