Java 使用泛型避免instanceof
我需要添加到子属性(ProductOption和ProductAttribute)列表中,这些子属性是名为Product的父对象的属性。这三个类都扩展了一个抽象类CMS 我想一般性地调用方法“attachChildToParent”,但我延迟了Java 使用泛型避免instanceof,java,generics,Java,Generics,我需要添加到子属性(ProductOption和ProductAttribute)列表中,这些子属性是名为Product的父对象的属性。这三个类都扩展了一个抽象类CMS 我想一般性地调用方法“attachChildToParent”,但我延迟了的实例并将其转换为产品,从而延迟了不可避免的过程 有没有一种方法可以让我写这篇文章,这样我就可以避免演员阵容 要测试: package puzzler; import java.util.ArrayList; import java.util.List;
的实例并将其转换为产品,从而延迟了不可避免的过程
有没有一种方法可以让我写这篇文章,这样我就可以避免演员阵容
要测试:
package puzzler;
import java.util.ArrayList;
import java.util.List;
public class Tester {
public static void main(String[] args) {
Product p = new Product();
ProductAttribute pa = new ProductAttribute();
ProductOffering po = new ProductOffering();
List<ProductAttribute> lpa = new ArrayList<ProductAttribute>();
List<ProductOffering> lpo = new ArrayList<ProductOffering>();
attachChildToParent(lpa, p);
}
static void attachChildToParent(List<? extends CMS> listChild, Product parent) {
for (CMS cmsItem : listChild) {
parent.attach(cmsItem);
}
}
}
二级儿童
package puzzler;
import puzzler.CMS;
public class ProductOffering extends CMS {
String node;
public String getNode() {
return node;
}
public void setNode(String node) {
this.node = node;
}
}
您可以通过使用访问者模式来解决铸造问题:在CMS
类中,添加一个新的(抽象)方法attachTo(产品父级)
。在每个子类中,您都可以实现此方法来调用父类上的attach,正确的函数将得到解决。您可以使用visitor模式解决铸造问题:在您的CMS
类中,添加一个新的(抽象)方法attachTo(产品父类)
。在每个子类中,您都可以实现此方法来调用父类上的attach,并将解析正确的函数。覆盖
public void attach(ProductOffering cms) {
this.getLpo().add(cms);
}
public void attach(ProductAttribute cms) {
this.getLpa().add(cms);
}
覆盖
public void attach(ProductOffering cms) {
this.getLpo().add(cms);
}
public void attach(ProductAttribute cms) {
this.getLpa().add(cms);
}
委派给子类:
public void attach(CMS cms) {
cms.callAdd(this);
}
在CMS上添加:
public abstract void callAdd(Product product);
在ProductOffering上添加:
public void callAdd(Product product) {
getLpo().add(this)
}
ProductAttribute…的类似委托给子类:
public void attach(CMS cms) {
cms.callAdd(this);
}
在CMS上添加:
public abstract void callAdd(Product product);
在ProductOffering上添加:
public void callAdd(Product product) {
getLpo().add(this)
}
ProductAttribute的一个类似例子…有一些方法可以避免这种情况,但泛型不能。泛型允许您编写允许避免强制转换的代码,但当您需要避免instanceof
时,它没有帮助。主要原因是,所有具有泛型类型的变量在内部都被视为Object
这就是为什么当您从attachChildToParent()
调用它时,编译器使用泛型attach(CMS)
方法:要附加的子对象的类型将是CMS
——编译器无法保留您在调用attachChildToParent()时使用的类型
唯一的解决方案是在子对象中编写附加方法:
public class ProductAttribute extends CMS {
@Override
public void attachTo( Product p ) {
p.getLpo().add( this );
}
}
有一些方法可以避免这种情况,但泛型不能。泛型允许您编写允许避免强制转换的代码,但当您需要避免instanceof
时,它没有帮助。主要原因是,所有具有泛型类型的变量在内部都被视为Object
这就是为什么当您从attachChildToParent()
调用它时,编译器使用泛型attach(CMS)
方法:要附加的子对象的类型将是CMS
——编译器无法保留您在调用attachChildToParent()时使用的类型
唯一的解决方案是在子对象中编写附加方法:
public class ProductAttribute extends CMS {
@Override
public void attachTo( Product p ) {
p.getLpo().add( this );
}
}
仿制药不能解决你的问题。由于在之后丢失了特定于实例的信息,泛型无法解决您的问题。由于您在之后丢失了特定于实例的信息,我已经很久没有使用java了,但在C#中,您可以这样声明:FatherType foo=new ChildType();ListI已经很久没有使用java了,但在C#中,可以这样做声明:FatherType foo=new ChildType();这个代码已经存在了:问题是调用站点只知道这个超类,它在run-time.Doh中并没有消除歧义!对不起,我刚才仔细看了一下,你是对的。我不认为泛型会有帮助,因为运行时类型擦除。我会想一想,但是因为您有一个逻辑分支,所以在将实际实现传递到方法时,需要在运行时区分它。您可能需要进一步重新思考这个问题。这段代码已经存在:问题是调用站点只知道超类,在运行时它不会消除歧义。Doh!对不起,我刚才仔细看了一下,你是对的。我不认为泛型会有帮助,因为运行时类型擦除。我会想一想,但是因为您有一个逻辑分支,所以在将实际实现传递到方法时,需要在运行时区分它。你可能需要进一步思考这个问题。谢谢。这是我最初的方法,但它假设父对象始终是产品。事实上,这种情况可能永远都会发生,我想得太多了。但是这个难题确实困扰着我。您也可以创建一个接口,并在attachTo()
中将其用作参数类型。这将允许您说“这个孩子可以附加到任何具有方法getLpo()
”的东西上。”谢谢。这是我最初的方法,但它假设父对象始终是产品。事实上,这种情况可能永远都会发生,我想得太多了。但是这个难题确实困扰着我。您也可以创建一个接口,并在attachTo()
中将其用作参数类型。这将允许您说“这个子对象可以附加到任何具有方法getLpo()
的对象。”