[英]Java - Dynamically creating concrete type of an Interface?
In my java class below I create a product and calculate the shipping as follows:在下面的 java 类中,我创建了一个产品并按如下方式计算运费:
public static void main(String[] args) {
// create product
Product product = new Product();
// calculate shipping
ShippingCalculator usaShippingCalculator = new USAShippingCalculator();
usaShippingCalculator.calculatePrice(product);
// todo - how to replace above with dynamic logic around what calculator to use?
}
Note that I have 2 different shipping calculators:请注意,我有 2 个不同的运费计算器:
USAShippingCalculator
RestofWorldShippingCalculator
Both implement the ShippingCalculator
interface, shown below:两者都实现了
ShippingCalculator
接口,如下所示:
public interface ShippingCalculator {
void calculatePrice(Product product);
}
Note that I have hardcoded above to use the USAShippingCalculator
, however what I want to do is dynamically use the calculator that corresponds to the products country of origin - this will be a field in the Product object: String countryOfOrigin.
请注意,我在上面进行了硬编码以使用
USAShippingCalculator
,但是我想要做的是动态使用与产品原产国相对应的计算器 - 这将是产品对象中的一个字段: String countryOfOrigin.
How can I do so?我该怎么做?
You can create a enum Calculator type with two instances USA and REST_OF_THE_WORLD.您可以创建一个具有两个实例 USA 和 REST_OF_THE_WORLD 的枚举计算器类型。 You can then implement ShippingCalculator to your enum overriding the calculatePrice with the corresponding shipping calculator.
然后,您可以为您的枚举实现 ShippingCalculator,使用相应的运费计算器覆盖 calculatePrice。
class Test {
enum Origins {
USA, REST_OF_THE_WORLD
}
public static void main(String[] args) {
// Product country of origin.
Product product = new Product(Origins.USA.toString());
// Get the country of origin from Product.
String countryOfOrigin = product.countryOfOrigin;
// Iterate through each instance. Example. USA, REST_OF_THE_WORLD, etc.
for(Calculator c : Calculator.values()) {
// Find the calculator that corresponds to the product origin.
if (c.name().equals(countryOfOrigin)) {
// Calculate the price using the corresponding calculator.
// In this case it would be USA.
c.calculatePrice(product);
}
}
}
}
enum Calculator implements ShippingCalculator {
REST_OF_THE_WORLD {
@Override
public void calculatePrice(Product product) {
RestofWorldShippingCalculator world = new RestofWorldShippingCalculator();
world.calculatePrice(product);
System.out.println("WORLD PRICE " + world.value);
}
},
USA {
@Override
public void calculatePrice(Product product) {
USAShippingCalculator usa = new USAShippingCalculator();
usa.calculatePrice(product);
System.out.println("USA PRICE " + usa.value);
}
}
}
interface ShippingCalculator {
void calculatePrice(Product product);
}
class RestofWorldShippingCalculator implements ShippingCalculator{
double value;
@Override
public void calculatePrice(Product product) {
value = product.i * 1.05;
}
}
class USAShippingCalculator implements ShippingCalculator{
double value;
@Override
public void calculatePrice(Product product) {
value = product.i * 1.10;
}
}
class Product {
String countryOfOrigin;
int i = 5;
Product(String countryOfOrigin) {
this.countryOfOrigin = countryOfOrigin;
}
}
If you are unlikely to need these calculators anywhere else in your code, you could use anonymous inner classes.如果您不太可能在代码的其他任何地方需要这些计算器,则可以使用匿名内部类。
public static void main(String[] args) {
// create product
Product product = new Product();
ShippingCalculator shippingCalculator;
// calculate shipping
if(product.countryOfOrigin.equals("USA"))
shippingCalculator = new ShippingCalculator(){
void calculatePrice(Product product){
//do usa calculation
}
}
else
shippingCalculator = new ShippingCalculator() {
void calculatePrice(Product product){
//do non-usa calculation
}
}
shippingCalculator.calculatePrice(product);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.