<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## [匿名內部類](https://lingcoder.gitee.io/onjava8/#/book/11-Inner-Classes?id=%e5%8c%bf%e5%90%8d%e5%86%85%e9%83%a8%e7%b1%bb) 下面的例子看起來有點奇怪: ~~~ // innerclasses/Parcel7.java // Returning an instance of an anonymous inner class public class Parcel7 { public Contents contents() { return new Contents() { // Insert class definition private int i = 11; @Override public int value() { return i; } }; // Semicolon required } public static void main(String[] args) { Parcel7 p = new Parcel7(); Contents c = p.contents(); } } ~~~ `contents()`方法將返回值的生成與表示這個返回值的類的定義結合在一起!另外,這個類是匿名的,它沒有名字。更糟的是,看起來似乎是你正要創建一個**Contents**對象。但是然后(在到達語句結束的分號之前)你卻說:“等一等,我想在這里插入一個類的定義。” 這種奇怪的語法指的是:“創建一個繼承自**Contents**的匿名類的對象。”通過**new**表達式返回的引用被自動向上轉型為對**Contents**的引用。上述匿名內部類的語法是下述形式的簡化形式: ~~~ // innerclasses/Parcel7b.java // Expanded version of Parcel7.java public class Parcel7b { class MyContents implements Contents { private int i = 11; @Override public int value() { return i; } } public Contents contents() { return new MyContents(); } public static void main(String[] args) { Parcel7b p = new Parcel7b(); Contents c = p.contents(); } } ~~~ 在這個匿名內部類中,使用了默認的構造器來生成**Contents**。下面的代碼展示的是,如果你的基類需要一個有參數的構造器,應該怎么辦: ~~~ // innerclasses/Parcel8.java // Calling the base-class constructor public class Parcel8 { public Wrapping wrapping(int x) { // Base constructor call: return new Wrapping(x) { // [1] @Override public int value() { return super.value() * 47; } }; // [2] } public static void main(String[] args) { Parcel8 p = new Parcel8(); Wrapping w = p.wrapping(10); } } ~~~ * \[1\] 將合適的參數傳遞給基類的構造器。 * \[2\] 在匿名內部類末尾的分號,并不是用來標記此內部類結束的。實際上,它標記的是表達式的結束,只不過這個表達式正巧包含了匿名內部類罷了。因此,這與別的地方使用的分號是一致的。 盡管**Wrapping**只是一個具有具體實現的普通類,但它還是被導出類當作公共“接口”來使用。 ~~~ // innerclasses/Wrapping.java public class Wrapping { private int i; public Wrapping(int x) { i = x; } public int value() { return i; } } ~~~ 為了多樣性,**Wrapping**擁有一個要求傳遞一個參數的構造器。 在匿名類中定義字段時,還能夠對其執行初始化操作: ~~~ // innerclasses/Parcel9.java public class Parcel9 { // Argument must be final or "effectively final" // to use within the anonymous inner class: public Destination destination(final String dest) { return new Destination() { private String label = dest; @Override public String readLabel() { return label; } }; } public static void main(String[] args) { Parcel9 p = new Parcel9(); Destination d = p.destination("Tasmania"); } } ~~~ 如果定義一個匿名內部類,并且希望它使用一個在其外部定義的對象,那么編譯器會要求其參數引用是**final**的(也就是說,它在初始化后不會改變,所以可以被當作**final**),就像你在`destination()`的參數中看到的那樣。這里省略掉**final**也沒問題,但是通常最好加上**final**作為一種暗示。 如果只是簡單地給一個字段賦值,那么此例中的方法是很好的。但是,如果想做一些類似構造器的行為,該怎么辦呢?在匿名類中不可能有命名構造器(因為它根本沒名字!),但通過實例初始化,就能夠達到為匿名內部類創建一個構造器的效果,就像這樣: ~~~ // innerclasses/AnonymousConstructor.java // Creating a constructor for an anonymous inner class abstract class Base { Base(int i) { System.out.println("Base constructor, i = " + i); } public abstract void f(); } public class AnonymousConstructor { public static Base getBase(int i) { return new Base(i) { { System.out.println( "Inside instance initializer"); } @Override public void f() { System.out.println("In anonymous f()"); } }; } public static void main(String[] args) { Base base = getBase(47); base.f(); } } ~~~ 輸出為: ~~~ Base constructor, i = 47 Inside instance initializer In anonymous f() ~~~ 在此例中,不要求變量一定是**final**的。因為被傳遞給匿名類的基類的構造器,它并不會在匿名類內部被直接使用。 下例是帶實例初始化的"parcel"形式。注意`destination()`的參數必須是**final**的,因為它們是在匿名類內部使用的(譯者注:即使不加**final**, Java 8 的編譯器也會為我們自動加上**final**,以保證數據的一致性)。 ~~~ // innerclasses/Parcel10.java // Using "instance initialization" to perform // construction on an anonymous inner class public class Parcel10 { public Destination destination(final String dest, final float price) { return new Destination() { private int cost; // Instance initialization for each object: { cost = Math.round(price); if(cost > 100) System.out.println("Over budget!"); } private String label = dest; @Override public String readLabel() { return label; } }; } public static void main(String[] args) { Parcel10 p = new Parcel10(); Destination d = p.destination("Tasmania", 101.395F); } } ~~~ 輸出為: ~~~ Over budget! ~~~ 在實例初始化操作的內部,可以看到有一段代碼,它們不能作為字段初始化動作的一部分來執行(就是**if**語句)。所以對于匿名類而言,實例初始化的實際效果就是構造器。當然它受到了限制-你不能重載實例初始化方法,所以你僅有一個這樣的構造器。 匿名內部類與正規的繼承相比有些受限,因為匿名內部類既可以擴展類,也可以實現接口,但是不能兩者兼備。而且如果是實現接口,也只能實現一個接口。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看