具有 Java 的 Composite 的层次结构问题
Hierarchy issue on Composite with Java
我正在尝试在 Java 上使用复合模式来做报告,但我显然忘记了层次结构和方法重载的工作原理。
假设我有以下型号:
public class Product {
public String get(){
return "Product";
}
}
public class BProduct extends Product {
public String getB() {
return "BBBBB";
}
}
public class CProduct extends Product {
public String getC() {
return "CCCCC";
}
}
以及以下转换器:
import java.util.List;
public class Converter {
private List<Converter> converters;
public Converter() {
}
public Converter(List<Converter> converters) {
this.converters = converters;
}
public void execute(Product product) {
for (Converter converter : converters) {
converter.execute(product);
}
}
}
public class BConverter extends Converter {
@Override
public void execute(Product product) {
innerExecute(product);
}
public void innerExecute(Product product) {
System.out.println(product.get() + " done on B normal.");
}
public void innerExecute(BProduct b) {
System.out.println(b.getB() + " done on B special.");
}
}
public class CConverter extends Converter {
@Override
public void execute(Product product) {
System.out.println(product.get() + " done on C normal.");
}
public void execute(CProduct c) {
System.out.println(c.getC() + " done on C special.");
}
}
使用以下测试对其进行测试:
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class ProductConverterTest {
@Test
public void test() {
List<Converter> converters = new ArrayList<>();
converters.add(new BConverter());
converters.add(new CConverter());
Converter converter = new Converter(converters);
List<Product> list = new ArrayList<>();
list.add(new Product());
list.add(new BProduct());
list.add(new CProduct());
for (Product product : list) {
converter.execute(product);
}
}
}
作为输出获取:
Product done on B normal.
Product done on C normal.
Product done on B normal.
Product done on C normal.
Product done on B normal.
Product done on C normal.
当我想要的是:
Product done on B normal.
Product done on C normal.
BBBBB done on B special.
Product done on C normal.
Product done on B normal.
CCCCC done on C special.
注意: 我想在不使用 instanceof
的情况下执行此操作。我已经知道如何使用它了。我想知道的是没有它能不能完成。
你在子转换器中的执行方法总是调用上级转换器的内部执行方法class。在您的示例中,从 subclasses 中删除 innerExecute(Product proeuct)。
您还可以尝试覆盖产品中的 toString()-Method 而不是 get-method。然后为执行方法使用一个接口。
此行为的原因是 #execute
方法被重载。选择调用哪个重载方法是在编译时做出的。为了使其按您的意愿工作,您必须使用动态选择,这将导致 instanceOf
检查或覆盖方法或 pass/retrieve class product
并进行比较:
public class Converter {
private List<Converter> converters;
public Converter() {
}
public Converter(List<Converter> converters) {
this.converters = converters;
}
public void execute(Product product) {
for (Converter converter : converters) {
converter.execute(product);
}
}
}
public class BConverter extends Converter {
@Override
public void execute(Product product) {
if (product.getClass() == BProduct.class) {
innerExecute((BProduct)product);
} else {
innerExecute(product);
}
}
public void innerExecute(Product product) {
System.out.println(product.get() + " done on B normal.");
}
public void innerExecute(BProduct b) {
System.out.println(b.getB() + " done on B special.");
}
}
public class CConverter extends Converter {
@Override
public void execute(Product product) {
if (product.getClass() == CProduct.class) {
innerExecute((CProduct)product);
} else {
innerExecute(product);
}
}
public void innerExecute(Product product) {
System.out.println(product.get() + " done on C normal.");
}
public void innerExecute(CProduct b) {
System.out.println(b.getC() + " done on C special.");
}
}
我正在尝试在 Java 上使用复合模式来做报告,但我显然忘记了层次结构和方法重载的工作原理。
假设我有以下型号:
public class Product {
public String get(){
return "Product";
}
}
public class BProduct extends Product {
public String getB() {
return "BBBBB";
}
}
public class CProduct extends Product {
public String getC() {
return "CCCCC";
}
}
以及以下转换器:
import java.util.List;
public class Converter {
private List<Converter> converters;
public Converter() {
}
public Converter(List<Converter> converters) {
this.converters = converters;
}
public void execute(Product product) {
for (Converter converter : converters) {
converter.execute(product);
}
}
}
public class BConverter extends Converter {
@Override
public void execute(Product product) {
innerExecute(product);
}
public void innerExecute(Product product) {
System.out.println(product.get() + " done on B normal.");
}
public void innerExecute(BProduct b) {
System.out.println(b.getB() + " done on B special.");
}
}
public class CConverter extends Converter {
@Override
public void execute(Product product) {
System.out.println(product.get() + " done on C normal.");
}
public void execute(CProduct c) {
System.out.println(c.getC() + " done on C special.");
}
}
使用以下测试对其进行测试:
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class ProductConverterTest {
@Test
public void test() {
List<Converter> converters = new ArrayList<>();
converters.add(new BConverter());
converters.add(new CConverter());
Converter converter = new Converter(converters);
List<Product> list = new ArrayList<>();
list.add(new Product());
list.add(new BProduct());
list.add(new CProduct());
for (Product product : list) {
converter.execute(product);
}
}
}
作为输出获取:
Product done on B normal.
Product done on C normal.
Product done on B normal.
Product done on C normal.
Product done on B normal.
Product done on C normal.
当我想要的是:
Product done on B normal.
Product done on C normal.
BBBBB done on B special.
Product done on C normal.
Product done on B normal.
CCCCC done on C special.
注意: 我想在不使用 instanceof
的情况下执行此操作。我已经知道如何使用它了。我想知道的是没有它能不能完成。
你在子转换器中的执行方法总是调用上级转换器的内部执行方法class。在您的示例中,从 subclasses 中删除 innerExecute(Product proeuct)。
您还可以尝试覆盖产品中的 toString()-Method 而不是 get-method。然后为执行方法使用一个接口。
此行为的原因是 #execute
方法被重载。选择调用哪个重载方法是在编译时做出的。为了使其按您的意愿工作,您必须使用动态选择,这将导致 instanceOf
检查或覆盖方法或 pass/retrieve class product
并进行比较:
public class Converter {
private List<Converter> converters;
public Converter() {
}
public Converter(List<Converter> converters) {
this.converters = converters;
}
public void execute(Product product) {
for (Converter converter : converters) {
converter.execute(product);
}
}
}
public class BConverter extends Converter {
@Override
public void execute(Product product) {
if (product.getClass() == BProduct.class) {
innerExecute((BProduct)product);
} else {
innerExecute(product);
}
}
public void innerExecute(Product product) {
System.out.println(product.get() + " done on B normal.");
}
public void innerExecute(BProduct b) {
System.out.println(b.getB() + " done on B special.");
}
}
public class CConverter extends Converter {
@Override
public void execute(Product product) {
if (product.getClass() == CProduct.class) {
innerExecute((CProduct)product);
} else {
innerExecute(product);
}
}
public void innerExecute(Product product) {
System.out.println(product.get() + " done on C normal.");
}
public void innerExecute(CProduct b) {
System.out.println(b.getC() + " done on C special.");
}
}