Эккель Брюс
Шрифт:
}
} ///:-
Анонимные внутренние классы
Параметризация также может применяться к внутренним классам и анонимным внутренним классам. Пример реализации интерфейса Generator с использованием анонимных внутренних классов:
//: generics/BankTeller.java
II Очень простая имитация банковского обслуживания.
import java.util.*;
import net.mindview.util.*;
class Customer {
private static long counter = 1; private final long id = counter++; private Customer {}
public String toStringO { return "Customer " + id; } // Метод для получения объектов Generator: public static Generator<Customer> generatorO { return new Generator<Customer>
public Customer nextO { return new CustomerO; }
class Teller {
private static long counter = 1; private final long id = counter++; private TellerO {}
public String toStringO { return "Teller " + id; } // Синглетный объект Generator: public static Generator<Teller> generator = new Generator<Teller> {
public Teller next О { return new TellerO; }
}:
}
public class BankTeller {
public static void serve(Teller t, Customer c) {
System.out.printin(t + " обслуживает " + с);
}
public static void main(String[] args) { Random rand = new Random(47); Queue<Customer> line = new LinkedList<Customer>; Generators.fillOine, Customer, generator 0, 15): List<Teller> tellers = new ArrayList<Teller>; Generators.filKtellers, Teller.generator, 4); for(Customer с : line)
serve(tellers.get(rand.nextlnt(tellers.size)), c);
}
} /* Output:
Teller
3
обслуживает
Customer
1
Teller
2
обслуживает
Customer
2
Teller
3
обслуживает
Customer
3
Teller
1
обслуживает
Customer
4
Teller
1
обслуживает
Customer
5
Teller
3
обслуживает
Customer
6
Teller
1
обслуживает
Customer
7
Teller
2
обслуживает
Customer
8
Teller
3
обслуживает
Customer
9
Teller
3
обслуживает
Customer
10
Teller
2
обслуживает
Customer
11
Teller
4
обслуживает
Customer
12
Teller
2
обслуживает
Customer
13
Teller
1
обслуживает
Customer
14
Teller
1
обслуживает
Customer
15
*///•-
И Customer, и Teller содержат приватные конструкторы, поэтому для создания их объектов пользователь вынужден использовать объекты Generator. Customer содержит метод generator, который при каждом вызове создает новый объект Generator<Customer>. На случай, если множественные объекты Generator вам не понадобятся, в Teller создается синглетный открытый объект generator. Оба подхода продемонстрированы в вызовах fill внутри main.
Поскольку метод generator в Customer и объект Generator в Teller являются статическими, они не могут быть частью интерфейса, поэтому «обобщить» эту"
конкретную идиому не удастся. Несмотря на это обстоятельство, она достаточно хорошо работает в методе fill.
Построение сложных моделей
К числу важных преимуществ параметризации относится простота и надежность создания сложных моделей. Например, можно легко создать список (List) с элементами-кортежами:
//: generics/TupleList.java
// Построение сложных параметризованных типов путем объединения
import java.util.*;
import net.mindview util.*;
public class TupleList<A,B.C.D> extends ArrayList<FourTuple<A,B,C.D» {
public static void main(String[] args) {
TupleList<Vehicle, Amphibian. String. Integer> tl =
new TupleList<Vehicle. Amphibian, String. Integer>; tl.add(TupleTest.hO); tl.add(TupleTest.hO):
for(FourTuple<Vehicle.Amphibian.String.Integer> v tl) System.out.println(i);