1

我需要添加到子属性列表(ProductOption 和 ProductAttribute)中,这些子属性是名为 Product 的父对象的属性。这三个类都扩展了一个抽象类 CMS。

我想一般地调用方法“attachChildToParent”,但我通过推迟instanceof和强制转换到产品来延迟不可避免的事情。

有没有办法我可以通用地写这个,这样我就可以避免演员表?

去测试:

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 java.util.List;

abstract class CMS {
    String node;
}
public class Product extends CMS {
    List<ProductAttribute> lpa;
    List<ProductOffering> lpo;

    public List<ProductAttribute> getLpa() {
        return lpa;
    }

    public void setLpa(List<ProductAttribute> lpa) {
        this.lpa = lpa;
    }

    public List<ProductOffering> getLpo() {
        return lpo;
    }

    public void setLpo(List<ProductOffering> lpo) {
        this.lpo = lpo;
    }

    public void attach(ProductAttribute childNode) {
        this.getLpa().add(childNode);
    }

    public void attach(ProductOffering childNode) {
        this.getLpo().add(childNode);
    }

    //  I want to avoid this.  Defeats the purpose of generics.
    public void attach(CMS cms) {
        if (cms instanceof ProductOffering) {
            this.getLpo().add((ProductOffering) cms);
        } else         {
            if (cms instanceof ProductAttribute) {
                this.getLpa().add((ProductAttribute) cms);
            }
        }
    }
}

儿童班 1

package puzzler;

import puzzler.CMS;

public class ProductAttribute extends CMS {
    String node;

    public String getNode() {
        return node;
    }

    public void setNode(String node) {
        this.node = node;
    }
}

儿童班 2

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;
    }
}
4

5 回答 5

5

您可以使用访问者模式解决强制转换问题:在您的CMS类中,添加一个新的(抽象)方法attachTo(Product parent)。在每一个子类中,都可以实现这个方法在父类上调用attach,正确的函数就会被解析。

于 2012-08-17T12:31:09.237 回答
2

委托给子类:

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 的类似...

于 2012-08-17T12:35:38.263 回答
0

覆盖?

public void attach(ProductOffering cms) {
   this.getLpo().add(cms);
}

public void attach(ProductAttribute cms) {
   this.getLpa().add(cms);
}
于 2012-08-17T12:33:36.477 回答
0

有一些方法可以避免这种情况,但不能使用泛型。泛型允许您编写允许避免强制转换的代码,但是当您需要避免instanceof. 主要原因是所有具有泛型类型的变量都被视为Object内部变量。

这就是为什么编译器attach(CMS)在您调用它时使用泛型方法的原因attachChildToParent(): 要附加的子项的类型将是CMS- 编译器无法保留您在调用时使用的类型attachChildToParent()

唯一的解决方案是在孩子中编写一个附加方法:

public class ProductAttribute extends CMS {
    @Override
    public void attachTo( Product p ) {
        p.getLpo().add( this );
    }
}
于 2012-08-17T12:35:39.300 回答
0

泛型不能解决你的问题。由于之后您会丢失实例特定信息,<? extends CMS>因此 List 中的所有元素都是CMS唯一的子元素。

为什么不添加简单的方法,它将两个列表都作为参数,适合您的设计并解决您的问题,它也很有效

public void attach(List<ProductAttribute> lpa, List<ProductOffering> lpo) {
    this.lpa.addAll(lpa);
    this.lpo.addAll(lpo);
}
于 2012-08-17T13:08:28.887 回答