2015-09-07 11:44:36 -06:00
|
|
|
// patterns/trash/Trash.java
|
2020-10-07 13:35:40 -06:00
|
|
|
// (c)2020 MindView LLC: see Copyright.txt
|
2015-11-15 15:51:35 -08:00
|
|
|
// We make no guarantees that this code is fit for any purpose.
|
2016-09-23 13:23:35 -06:00
|
|
|
// Visit http://OnJava8.com for more book information.
|
2016-01-25 18:05:55 -08:00
|
|
|
// Base class for Trash recycling examples
|
2015-06-15 17:47:35 -07:00
|
|
|
package patterns.trash;
|
|
|
|
import java.util.*;
|
|
|
|
import java.lang.reflect.*;
|
|
|
|
|
|
|
|
public abstract class Trash {
|
|
|
|
private double weight;
|
|
|
|
public Trash(double wt) { weight = wt; }
|
|
|
|
public Trash() {}
|
|
|
|
public abstract double value();
|
|
|
|
public double weight() { return weight; }
|
|
|
|
// Sums the value of Trash in a bin:
|
2015-11-03 12:00:44 -08:00
|
|
|
static double val;
|
2015-06-15 17:47:35 -07:00
|
|
|
public static <T extends Trash>
|
|
|
|
void sumValue(List<? extends T> bin) {
|
2015-11-03 12:00:44 -08:00
|
|
|
val = 0.0f;
|
|
|
|
bin.forEach( t -> {
|
2015-06-15 17:47:35 -07:00
|
|
|
val += t.weight() * t.value();
|
|
|
|
System.out.println("weight of " +
|
2015-11-03 12:00:44 -08:00
|
|
|
// RTTI gets type information
|
|
|
|
// about the class:
|
2015-06-15 17:47:35 -07:00
|
|
|
t.getClass().getName() +
|
|
|
|
" = " + t.weight());
|
2015-11-03 12:00:44 -08:00
|
|
|
});
|
2015-06-15 17:47:35 -07:00
|
|
|
System.out.println("Total value = " + val);
|
|
|
|
}
|
2015-11-03 12:00:44 -08:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
// Print correct subclass name:
|
|
|
|
return getClass().getName() +
|
|
|
|
" w:" + weight() + " v:" +
|
|
|
|
String.format("%.2f", value());
|
|
|
|
}
|
|
|
|
// Remainder of class supports dynamic creation:
|
2015-06-15 17:47:35 -07:00
|
|
|
public static class CannotCreateTrashException
|
2015-11-03 12:00:44 -08:00
|
|
|
extends RuntimeException {
|
|
|
|
public CannotCreateTrashException(Exception why) {
|
|
|
|
super(why);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static class TrashClassNotFoundException
|
|
|
|
extends RuntimeException {
|
|
|
|
public TrashClassNotFoundException(Exception why) {
|
|
|
|
super(why);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static class Info {
|
|
|
|
public String id;
|
|
|
|
public double data;
|
|
|
|
public Info(String name, double data) {
|
|
|
|
id = name;
|
|
|
|
this.data = data;
|
|
|
|
}
|
|
|
|
}
|
2015-06-15 17:47:35 -07:00
|
|
|
private static List<Class> trashTypes =
|
|
|
|
new ArrayList<>();
|
|
|
|
@SuppressWarnings("unchecked")
|
2015-11-03 12:00:44 -08:00
|
|
|
public static <T extends Trash> T factory(Info info) {
|
2015-06-15 17:47:35 -07:00
|
|
|
for(Class trashType : trashTypes) {
|
2015-11-03 12:00:44 -08:00
|
|
|
// Determine the type and create one:
|
2015-06-15 17:47:35 -07:00
|
|
|
if(trashType.getName().contains(info.id)) {
|
|
|
|
try {
|
|
|
|
// Get the dynamic constructor method
|
|
|
|
// that takes a double argument:
|
2017-01-09 14:26:12 -08:00
|
|
|
Constructor ctor =
|
|
|
|
trashType.getConstructor(double.class);
|
2015-06-15 17:47:35 -07:00
|
|
|
// Call the constructor to create a
|
|
|
|
// new object:
|
2020-10-07 17:06:42 -06:00
|
|
|
return
|
|
|
|
(T)ctor.newInstance(info.data);
|
2015-11-03 12:00:44 -08:00
|
|
|
} catch(Exception e) {
|
|
|
|
throw new CannotCreateTrashException(e);
|
2015-06-15 17:47:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-03 12:00:44 -08:00
|
|
|
// The necessary Class was not in the list. Try to
|
|
|
|
// load it, but it must be in your class path!
|
2015-06-15 17:47:35 -07:00
|
|
|
try {
|
|
|
|
System.out.println("Loading " + info.id);
|
|
|
|
trashTypes.add(Class.forName(info.id));
|
|
|
|
} catch(Exception e) {
|
2015-11-03 12:00:44 -08:00
|
|
|
throw new TrashClassNotFoundException(e);
|
2015-06-15 17:47:35 -07:00
|
|
|
}
|
|
|
|
// Loaded successfully. Recursive call
|
|
|
|
// should work this time:
|
|
|
|
return factory(info);
|
|
|
|
}
|
2015-09-07 11:44:36 -06:00
|
|
|
}
|