<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 泛型接口 泛型也可以應用于接口。例如 *生成器*,這是一種專門負責創建對象的類。實際上,這是 *工廠方法* 設計模式的一種應用。不過,當使用生成器創建新的對象時,它不需要任何參數,而工廠方法一般需要參數。生成器無需額外的信息就知道如何創建新對象。 一般而言,一個生成器只定義一個方法,用于創建對象。例如 `java.util.function` 類庫中的 `Supplier` 就是一個生成器,調用其 `get()` 獲取對象。`get()` 是泛型方法,返回值為類型參數 `T`。 為了演示 `Supplier`,我們需要定義幾個類。下面是個咖啡相關的繼承體系: ```java // generics/coffee/Coffee.java package generics.coffee; public class Coffee { private static long counter = 0; private final long id = counter++; @Override public String toString() { return getClass().getSimpleName() + " " + id; } } // generics/coffee/Latte.java package generics.coffee; public class Latte extends Coffee {} // generics/coffee/Mocha.java package generics.coffee; public class Mocha extends Coffee {} // generics/coffee/Cappuccino.java package generics.coffee; public class Cappuccino extends Coffee {} // generics/coffee/Americano.java package generics.coffee; public class Americano extends Coffee {} // generics/coffee/Breve.java package generics.coffee; public class Breve extends Coffee {} ``` 現在,我們可以編寫一個類,實現 `Supplier<Coffee>` 接口,它能夠隨機生成不同類型的 `Coffee` 對象: ```java // generics/coffee/CoffeeSupplier.java // {java generics.coffee.CoffeeSupplier} package generics.coffee; import java.util.*; import java.util.function.*; import java.util.stream.*; public class CoffeeSupplier implements Supplier<Coffee>, Iterable<Coffee> { private Class<?>[] types = { Latte.class, Mocha.class, Cappuccino.class, Americano.class, Breve.class }; private static Random rand = new Random(47); public CoffeeSupplier() {} // For iteration: private int size = 0; public CoffeeSupplier(int sz) { size = sz; } @Override public Coffee get() { try { return (Coffee) types[rand.nextInt(types.length)].newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } class CoffeeIterator implements Iterator<Coffee> { int count = size; @Override public boolean hasNext() { return count > 0; } @Override public Coffee next() { count--; return CoffeeSupplier.this.get(); } @Override public void remove() { throw new UnsupportedOperationException(); } } @Override public Iterator<Coffee> iterator() { return new CoffeeIterator(); } public static void main(String[] args) { Stream.generate(new CoffeeSupplier()) .limit(5) .forEach(System.out::println); for (Coffee c : new CoffeeSupplier(5)) { System.out.println(c); } } } ``` 輸出結果: ```java Americano 0 Latte 1 Americano 2 Mocha 3 Mocha 4 Breve 5 Americano 6 Latte 7 Cappuccino 8 Cappuccino 9 ``` 參數化的 `Supplier` 接口確保 `get()` 返回值是參數的類型。`CoffeeSupplier` 同時還實現了 `Iterable` 接口,所以能用于 *for-in* 語句。不過,它還需要知道何時終止循環,這正是第二個構造函數的作用。 下面是另一個實現 `Supplier<T>` 接口的例子,它負責生成 Fibonacci 數列: ```java // generics/Fibonacci.java // Generate a Fibonacci sequence import java.util.function.*; import java.util.stream.*; public class Fibonacci implements Supplier<Integer> { private int count = 0; @Override public Integer get() { return fib(count++); } private int fib(int n) { if(n < 2) return 1; return fib(n-2) + fib(n-1); } public static void main(String[] args) { Stream.generate(new Fibonacci()) .limit(18) .map(n -> n + " ") .forEach(System.out::print); } } ``` 輸出結果: ```java 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 ``` 雖然我們在 `Fibonacci` 類的里里外外使用的都是 `int` 類型,但是其參數類型卻是 `Integer`。這個例子引出了 Java 泛型的一個局限性:基本類型無法作為類型參數。不過 Java 5 具備自動裝箱和拆箱的功能,可以很方便地在基本類型和相應的包裝類之間進行轉換。通過這個例子中 `Fibonacci` 類對 `int` 的使用,我們已經看到了這種效果。 如果還想更進一步,編寫一個實現了 `Iterable` 的 `Fibnoacci` 生成器。我們的一個選擇是重寫這個類,令其實現 `Iterable` 接口。不過,你并不是總能擁有源代碼的控制權,并且,除非必須這么做,否則,我們也不愿意重寫一個類。而且我們還有另一種選擇,就是創建一個 *適配器* (Adapter) 來實現所需的接口,我們在前面介紹過這個設計模式。 有多種方法可以實現適配器。例如,可以通過繼承來創建適配器類: ```java // generics/IterableFibonacci.java // Adapt the Fibonacci class to make it Iterable import java.util.*; public class IterableFibonacci extends Fibonacci implements Iterable<Integer> { private int n; public IterableFibonacci(int count) { n = count; } @Override public Iterator<Integer> iterator() { return new Iterator<Integer>() { @Override public boolean hasNext() { return n > 0; } @Override public Integer next() { n--; return IterableFibonacci.this.get(); } @Override public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; } public static void main(String[] args) { for(int i : new IterableFibonacci(18)) System.out.print(i + " "); } } ``` 輸出結果: ```java 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 ``` 在 *for-in* 語句中使用 `IterableFibonacci`,必須在構造函數中提供一個邊界值,這樣 `hasNext()` 才知道何時返回 **false**,結束循環。
                  <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>

                              哎呀哎呀视频在线观看