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

📄 tij310.htm

📁 这也是我们java老师给我们的thinking in java的一些资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<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>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> t(CanFight x) { x.fight(); }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> u(CanSwim x) { x.swim(); }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> v(CanFly x) { x.fly(); }
  <font color=#0000ff>public</font> <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 h = <font color=#0000ff>new</font> Hero();
    t(h); <font color=#009900>// Treat it as a CanFight</font>
    u(h); <font color=#009900>// Treat it as a CanSwim</font>
    v(h); <font color=#009900>// Treat it as a CanFly</font>
    w(h); <font color=#009900>// Treat it as an ActionCharacter</font>
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>You can see that <b>Hero</b> combines the concrete class <b>ActionCharacter</b> with the interfaces <b>CanFight</b>, <b>CanSwim</b>, and <b>CanFly</b>. 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 size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1118" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Note that the signature for <b>fight(&#160;)</b> is the same in the <b>interface CanFight</b> and the class <b>ActionCharacter</b>, and that <b>fight(&#160;)</b> is <i>not</i> provided with a definition in <b>Hero</b>. The rule for an <b>interface</b> is that you can inherit from it (as you will see shortly), but then you&#146;ve got another <b>interface</b>. If you want to create an object of the new type, it must be a class with all definitions provided. Even though <b>Hero</b> does not explicitly provide a definition for <b>fight(&#160;)</b>, the definition comes along with <b>ActionCharacter</b>, so it is automatically provided and it&#146;s possible to create objects of <b>Hero</b>. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1119" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>In class <b>Adventure</b>, you can see that there are four methods that take as arguments the various interfaces and the concrete class. When a <b>Hero</b> object is created, it can be passed to any of these methods, which means it is being upcast to each <b>interface</b> in turn. Because of the way interfaces are designed in Java, this works without any particular effort on the part of the programmer. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1120" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Keep in mind that the core reason for interfaces is shown in the preceding 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 <b>abstract </b>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="Index699"></a><a name="Index700"></a><b>interface</b> or an <b>abstract</b> class? An <b>interface</b> gives you the benefits of an <b>abstract</b> class <i>and</i> the benefits of an <b>interface</b>, so if it&#146;s possible to create your base class without any method definitions or member variables, you should always prefer <b>interface</b>s to <b>abstract</b> classes. In fact, if you know something is going to be a base class, your first choice should be to make it an <b>interface</b>, and only if you&#146;re forced to have method definitions or member variables should you change to an <b>abstract</b> class, or if necessary a concrete class. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1121" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h4>
<a name="Heading6946"></a>Name collisions when combining interfaces<br></h4>
<p><a name="Index701"></a><a name="Index702"></a>You can encounter a small pitfall when implementing multiple interfaces. In the preceding example, both <b>CanFight</b> and <b>ActionCharacter</b> have an identical <b>void fight(&#160;)</b> method. This is not a problem, because the method is identical in both cases. But what if it isn&#146;t? Here&#146;s an example:<br></p>

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

<font color=#0000ff>interface</font> I1 { <font color=#0000ff>void</font> f(); }
<font color=#0000ff>interface</font> I2 { <font color=#0000ff>int</font> f(<font color=#0000ff>int</font> i); }
<font color=#0000ff>interface</font> I3 { <font color=#0000ff>int</font> f(); }
<font color=#0000ff>class</font> C { <font color=#0000ff>public</font> <font color=#0000ff>int</font> f() { <font color=#0000ff>return</font> 1; } }

<font color=#0000ff>class</font> C2 <font color=#0000ff>implements</font> I1, I2 {
  <font color=#0000ff>public</font> <font color=#0000ff>void</font> f() {}
  <font color=#0000ff>public</font> <font color=#0000ff>int</font> f(<font color=#0000ff>int</font> i) { <font color=#0000ff>return</font> 1; } <font color=#009900>// overloaded</font>
}

<font color=#0000ff>class</font> C3 <font color=#0000ff>extends</font> C <font color=#0000ff>implements</font> I2 {
  <font color=#0000ff>public</font> <font color=#0000ff>int</font> f(<font color=#0000ff>int</font> i) { <font color=#0000ff>return</font> 1; } <font color=#009900>// overloaded</font>
}

<font color=#0000ff>class</font> C4 <font color=#0000ff>extends</font> C <font color=#0000ff>implements</font> I3 {
  <font color=#009900>// Identical, no problem:</font>
  <font color=#0000ff>public</font> <font color=#0000ff>int</font> f() { <font color=#0000ff>return</font> 1; }
}

<font color=#009900>// Methods differ only by return type:</font>
<font color=#009900>//! class C5 extends C implements I1 {}</font>
<font color=#009900>//! interface I4 extends I1, I3 {} ///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The difficulty occurs because overriding, implementation, and overloading get unpleasantly mixed together, and overloaded methods cannot differ only by return type. When the last two lines are uncommented, the error messages say it all:<br></p>
<p><i>InterfaceCollision.java:23: f(&#160;) in C cannot implement f(&#160;) in I1; attempting to use incompatible return type </i><br><i>found : int</i><br><i>required: void</i><br><i>InterfaceCollision.java:24: interfaces I3 and I1 are incompatible; both define f(&#160;), but with different return type</i><br></p>
<p>Using the same method names in different interfaces that are intended to be combined generally causes confusion in the readability of the code, as well. Strive to avoid it. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1122" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc375545337"></a><a name="_Toc24775676"></a><a name="Heading6976"></a>Extending
an interface <br>with inheritance</h3>
<p>You can easily add new method declarations to an <a name="Index703"></a><a name="Index704"></a><b>interface</b> by using inheritance, and you can also combine several <b>interface</b>s into a new <b>interface</b> with inheritance. In both cases you get a new <b>interface</b>, as seen in this example:<br></p>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c08: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> VeryBadVampire <font color=#0000ff>implements</font> Vampire {
  <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>public</font> <font color=#0000ff>void</font> kill() {}
  <font color=#0000ff>public</font> <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>static</font> <font color=#0000ff>void</font> w(Lethal l) { l.kill(); }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    DangerousMonster barney = <font color=#0000ff>new</font> DragonZilla();
    u(barney);
    v(barney);
    Vampire vlad = <font color=#0000ff>new</font> VeryBadVampire();
    u(vlad);
    v(vlad);
    w(vlad);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p><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>. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1123" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The syntax used in <b>Vampire</b> works <i>only</i> when inheriting interfaces. Normally, you can use <a name="Index705"></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. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1124" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc24775677"></a><a name="Heading7029"></a>Grouping constants</h3>
<p>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 creating groups of constant values, much as you would with an <a name="Index706"></a><a name="Index707"></a><b>enum</b> in C or C++. For example:<br></p>

<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><p><br></p>
<p>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. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1125" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The fields in an <b>interface </b>are automatically <b>public</b>, so it&#146;s unnecessary to specify that. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1126" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>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&#146;t the extra type safety that C++&#146;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 &#147;magic numbers,&#148; and it produces very difficult-to-maintain code.) <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap08_1127" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>If you do want extra type safety, you can build a class like this:<sup><a name="fnB33" href="#fn33">[33]</a></sup><br></p>

⌨️ 快捷键说明

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