java,从超类初始化子类

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
   ...
}

i 成为基本对象的列表List<Base>

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

例:

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

我试图避免将基的每个属性手动初始化为子类Class

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

为什么将基类转换为子类(sence)是不可能的?为什么Java不允许我做以下事情:Subclass extends BaseClass

例:

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

然后

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

之后,对象应具有对象中的属性名称,并且属性为 nullsubbtitle

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

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


答案 1

如果有 ,则无法将其转换为 .这主要是因为该列表可能不包含 的实例。您能做的最好的事情是: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

编辑根据您的评论,听起来您希望使用实例列表作为开始来构建实例列表。一种方法是定义一个构造函数,它将 a 作为参数。SubClassBaseSubClassBase

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

答案 2

有一种方法:各种基于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