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
...
}
我成为Base对象的列表 List<Base>
但我需要相同的清单,但是 List<SubClass>
有没有办法从基类初始化子类?
例:
for(Base b: list){
SubClass sub = (SubClass)b; // Thats wrong i know
if(...){
sub.setSelected(true);
}
newList.add(sub);
}
我试图避免基础的每个属性的手动初始化 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
应该具有Object中的Attribute Name b
和 title
属性为null
为什么这不是java中的情况?
对不起,我的英语不好,
谢谢
如果你有 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
需要一个 Base
作为一个论点。
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);
}
有一种方法:各种Java Beans规范的操作。
例如:
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
。
您似乎拥有一个具有大量属性的类,并且没有简单的方法来设置它们。您现在遇到了一个问题,您需要一个具有附加属性的类,但您必须处理基类的混乱。
我建议,不要创建一个子类和转换,而是围绕丑陋的一个创建一个包装类:
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();