Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

}

public void count(Object obj) {

Class<?> type = obj .getClassO; i f(!baseType.i sAssi gnableFrom(type))

throw new RuntimeException(obj + " incorrect type: " + type + should be type or subtype of " + baseType);

countClass(type);

}

private void countClass(Class<?> type) { Integer quantity = get(type); put(type, quantity == null ? 1 : quantity +1); Class<?> superclass = type.getSuperclassO; if(superClass != null &&

baseType.i sAssi gnableFrom(superClass)) countClass(superClass);

}

public String toStringO {

StringBuilder result = new StringBuilder("{"); for(Map.Entry<Class<?>.Integer> pair : entrySetO) { result.append(pair.getKeyО.getSimpleName); result.append("="); res ul t.a ppend(pa i r.getVa1ue О); result.append(". ");

}

result.delete(result.1ength О -2, result. 1 ength О); result.append("}"); return result.toStringO;

}

} ///:-

Метод count получает Class для своего аргумента, а затем использует.isAs-signableFrom для проверки принадлежности объекта к интересующей вас иерархии. Метод countClas^O сначала производит подсчет для точного типа класса, а затем, если baseType допускает присваивание из суперкласса, рекурсивно вызывает countClass для суперкласса.

II: typeinfo/PetCount4.java

import typeinfo.pets.*,

import net.mindview.util.*;

import static net.mindview.util.Print.*;

public class PetCount4 {

public static void main(String[] args) {

TypeCounter counter = new TypeCounter(Pet.class); for(Pet pet : Pets.createArray(20)) {

printnb(pet.getClass.getSimpleNameO + " "); counter.count(pet);

}

printO:

print(counter); _ Л

продолжение &

}

} /* Output: (Пример)

Rat Manx Cymric Mutt Pug Cymric Pug Manx Cymric Rat EgyptianMau Hamster EgyptianMau Mutt Mutt Cymric Mouse Pug Mouse Cymric

{Mouse=2, Dog=6, Manx=7, EgyptianMau=2, Rodent=5, Pug=3, Mutt=3. Cymric=5, Cat=9. Hamster=l, Pet=20, Rat=2} *///:-

Как видно из результатов, подсчитываются как базовые, так и конкретные типы.

Регистрация фабрик

У построения объектов иерархии Pet есть один недостаток: каждый раз, когда в иерархию включается новый тип Pet, вы должны добавить его в LiteralPet-Creator.java. В системах с регулярным добавлением новых классов это может создать проблемы.

Первое, что приходит в голову, — добавить в каждый класс статический инициализатор, который добавлял бы свой класс в некий список. К сожалению, статические инициализаторы вызываются только при первой загрузке класса, поэтому возникает «порочный круг»: класс отсутствует в списке генератора, поэтому генератор не может создать объект этого класса, соответственно, класс не загрузится и не будет помещен в список.

По сути, вы вынуждены создать список вручную (разве что вы напишете утилиту, которая будет анализировать исходный код, а затем создавать и компилировать список). Вероятно, лучшее, что можно сделать, — это разместить список в одном централизованном, очевидном месте. Вероятно, лучшим местом для него будет базовый класс иерархии.

В этом разделе мы также внесем другое изменение: создание объекта будет передано самому классу с использованием паттерна «метод-фабрика». Метод-фабрика может вызываться полиморфно и создает объект соответствующего типа. В следующей упрощенной версии методом-фабрикой является метод create интерфейса Factory:

//: typeinfo/factory/Factory.java package typeinfo.factory:

public interface Factory<T> { T createO; } ///•-

Обобщенный параметр T позволяет create возвращать разные типы для разных реализаций Factory. Также при этом используется ковариантность возвращаемых типов.

В следующем примере базовый класс Part содержит список объектов-фабрик. Фабрики типов, которые должны создаваться методом createRandom, «регистрируются» в базовом классе включением в список partFactories:

//: typeinfo/RegisteredFactories.java II Регистрация фабрик в базовом классе import typeinfo.factory.*: import java util.*:

class Part {

public String toStringO {

return getClass.getSimpleName;

}

static List<Factory<? extends Part» partFactories = new ArrayList<Factory<? extends Part»0;

static {

// При вызове Collections addAllO выдается предупреждение // "unchecked generic array creation for varargs parameter" partFactories.add(new Fuel Filter FactoryO). partFactories add(new AirFilter FactoryO), partFactories add(new CabinAirFilter.FactoryO), partFactories add(new Oil Filter FactoryO); partFactories add(new FanBelt FactoryO); partFactories.add(new PowerSteeringBelt.Factory), partFactories add(new GeneratorBelt FactoryO),

}

private static Random rand = new Random(47);

public static Part createRandomO {

int n = rand nextInt(partFactories sizeO), return partFactories get(n) createO;

class Filter extends Part {}

class Fuel Filter extends Filter {

// Создание фабрики для каждого конкретного типа

public static class Factory

implements typeinfo factory.Factory<FuelFilter> {

public Fuel Filter createO { return new Fuel Filter О. }

}

}

class AirFilter extends Filter { public static class Factory implements typeinfo factory Factory<AirFilter> {

public AirFilter createO { return new AirFilterO. }

}

}

class CabinAirFiIter extends Filter { public static class Factory

implements typeinfo factory Factory<CabinAirFilter> { public CabinAi rFi Iter createO {

return new CabinAirFilter;

}

class Oil Filter extends Filter { public static class Factory implements typeinfo factory Factory<OilFilter> {

public Oil Filter createO { return new OilFilterO; }

Поделиться:
Популярные книги

На границе империй. Том 10. Часть 10

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 10

Тьма и Хаос

Владимиров Денис
6. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Тьма и Хаос

Имя нам Легион. Том 8

Дорничев Дмитрий
8. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 8

Излом

Осадчук Алексей Витальевич
10. Последняя жизнь
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Излом

Золото Советского Союза: назад в 1975. Книга 2

Майоров Сергей
2. Золото Советского Союза
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Золото Советского Союза: назад в 1975. Книга 2

Я – Стрела. Трилогия

Суббота Светлана
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
Я – Стрела. Трилогия

Первый среди равных. Книга IX

Бор Жорж
9. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга IX

Тринадцатый XII

NikL
12. Видящий смерть
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
7.00
рейтинг книги
Тринадцатый XII

Око василиска

Кас Маркус
2. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Око василиска

Солнечный флот

Вайс Александр
4. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Солнечный флот

Темный Лекарь

Токсик Саша
1. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь

Держать удар

Иванов Дмитрий
11. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Держать удар

Деревенщина в Пекине

Афанасьев Семён
1. Пекин
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Деревенщина в Пекине

Кодекс Охотника XXVIII

Винокуров Юрий
28. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника XXVIII