在PetCount3.PetCounter中的Map预加载了所有不同的Pet类。与预加载映射表不同的是,我们可以使用Class.isAssianableFrom(),并创建一个不局限于对Pet计数的通用工具。
//: net/mindview/util/TypeCounter.java
// Counts instances of a type family.
package net.mindview.util;
import java.util.*;
public class TypeCounter extends HashMap
private Class> baseType:
this.baseType = baseType;
}
public void count(Object obj) {
Class> type = obj.getClass();
if(!baseType.isAssignableFrom(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.getSuperclass();
if(superClass != null && baseType.isAssignableFrom(superClass)) countClass(superClass);
}
public String toString() {
StringBuilder result = new StringBuilder(”{");
for(Map.Entry
result.append(pair.getKey().getSimpleName());
result.append("=");
result.append(pair.getValue());
result.append(",");
}
result.delete(result.length()-2,result.length());
result.append("}");
return result.toString();
}
}///:~
count()方法获取其参数的的Class,然后使用isAssignableFrom()来执行运行时的检查,以校验你传递的对象确实属于我们感兴趣的继承结构。countClass()首先对该类的确切类型计数,然后,如果其超类可以赋值给baseType,countClass()将其超类上递归计数。
//: 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().getSimpleName()+" ");
counter.count(pet);
}
print();
print(counter);
}
}//:~
正如在输出中看到的那样,对基类型和确切类型都进行了计数。
练习11:(2)在typeinfo.pets类库中添加Gerbil,并修改本章中的所有示例,让它们适应这个新类。
练习12:(3)将第15章中的CoffeeGenerator.java类用于TypeCounter。
练习13:(3)将本章中的RegisteredFactories.java示例用于TypeCounter。



