12
public class Base {
  //long list of attributes
  // no Constructor using fields
  // no init methode 
  // i cannot change this class
}

现在我扩展了基类,如:

public class subClass extends Base{
   private boolean selected;

   ...
   getter und setter
   ...
}

我成为基础对象的列表List<Base>

但我需要相同的列表,但List<SubClass> 有没有办法从基类初始化子类?

例子:

for(Base b: list){
   SubClass sub = (SubClass)b; // Thats wrong i know
   if(...){
       sub.setSelected(true);
   }
   newList.add(sub);
}

我尽量避免将 Base 的每个 Attribute 手动初始化Class到 SubClass

我按照评论中的要求更新了我的问题:上面的设计只是一个例子。我的 QUESTIN 正是:

为什么将 BaseClass 转换为 SubClass (sence Subclass extends BaseClass) 是不可能的?为什么 Java 不允许我执行以下操作:

例子:

Class Base{
   private String name;
.....
}
Class SubClass extends Base{
   private String title;
}

然后

Base b = DBController.getById(...);
SubClass sub = (SubClass)b; 

之后,该对象sub应具有该对象的属性名称,b 并且该title属性为空

为什么在java中不是这种情况?

对不起我的英语不好,谢谢

4

3 回答 3

7

如果您有List<Base>,则无法将其转换为List<SubClass>。这主要是因为列表可能不包含SubClass. 你能做的最好的事情是:

List<SubClass> newList = new List<SubClass>();
for(Base b: list){
    if (b instanceof SubClass) {
        SubClass sub = (SubClass)b;
        . . .
        newList.add(sub);
    }
}

然而,一般来说,当你发现自己在做这种事情时,你的设计就有问题了。您可能希望避免子类化Base并改为使用组合

编辑根据您的评论,听起来您想SubClass使用实例列表Base作为开始来构建实例列表。一种方法是定义一个SubClass以 aBase作为参数的构造函数。

public class SubClass extends Base{
    private boolean selected;

    public SubClass() {
        // default constructor
    }

    public SubClass(Base original) {
        // copy constructor -- initialize some fields from
        // values in original, others with default values
    }
    ...
    getter und setter
    ...
}

然后您可以使用以下命令构建新列表:

List<SubClass> newList = new List<SubClass>();
for(Base b: list){
    SubClass sub = new SubClass(b);
    . . .
    newList.add(sub);
}
于 2013-04-04T04:05:59.997 回答
3

有一种方法:基于各种 Java Bean 规范的操作。

例如:

Commons BeanUtils

for( Base base: list ){
   SubClass sub = new SubClass();
   PropertyUtilsBean.copyProperties( sub, base );
   if(...){
       sub.setSelected(true);
   }
   newList.add(sub);
}

这基于同名的 get/setter 工作。不复制内部字段。

如果您需要复制内部字段,实际上使用javax.lang.reflect.

于 2013-06-23T09:48:20.050 回答
2

您似乎有一个具有很多属性的类,并且没有简单的方法来设置它们。您现在遇到了一个问题,您需要一个具有附加属性的类,但您必须处理基类的混乱。

我建议,不要创建子类和强制转换,而是围绕丑陋的类创建一个包装类:

public class BigDumbClass {
    // A lot of attributes
    // No Constructor
    // No init method
}

public class Wrapper {
    private BigDumbClass base;
    private boolean selected;

    public Wrapper(BigDumbClass base) {
        this.base = base;
        this.selected = false;
    }

    //getters and setters
}

现在,当您必须创建该新列表时,您可以将所有内容包装在旧列表中

List<BigDumbClass> oldList = someData();
List<Wrapper> wraps = aNewList();
for (BigDumbClass bigDumb : oldList) {
    Wrapper wrap = new Wrapper(bigDumb);
    if (someCondition()) {
        wrap.setSelected(true);
    }
    wraps.add(wrap);
}

理想情况下,BigDumbClass 将实现 Wrapper 也可以实现的接口,允许包装器将所有调用推迟到它已包装的实例。

public class BigDumbClass implements SharedInterface {
    // All the stuff outlined above
}

public class Wrapper implements SharedInterface {
    // All the stuff outlined above

    // Methods defined in SharedInterface
    public void doSomething() {
        base.doSomething();
    }
}

否则,您可以为实例提供一个 getter 并直接访问它。

BigDumbClass base = wrapper.getBase();
base.doSomething();
于 2013-04-04T04:55:05.940 回答