java中,从超类
public class Base {
//long list of attributes
// no Constructor using fields
// no init methode
// i cannot change this class
}
现在初始化子类我扩展基类,如:java中,从超类
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);
}
我尽量避免基Class
的每个属性的手动初始化子类
更新我的问题是在意见中的要求: 上面的设计仅仅是一个例子。我QUESTIN完全是:
为什么将BaseClass转换为子类(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
属性为null
为什么在java中不是这种情况?
对不起我的英文不好, 感谢
如果你有一个List<Base>
,则无法将其转换为List<SubClass>
。这主要是因为该列表可能不包含的实例。你能做的最好的是:
List<SubClass> newList = new List<SubClass>();
for(Base b: list){
if (b instanceof SubClass) {
SubClass sub = (SubClass)b;
. . .
newList.add(sub);
}
}
但是一般来说,当你发现自己在做这样的事情,有什么不对您的设计。您可能想要避免继承Base
并使用composition instead。
编辑根据您的意见,这听起来像你想用Base
实例作为开始的列表来构建实例的列表。一种方法是为定义一个构造函数,将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);
}
感谢您的答案。 List只有Object的基类型,所以它们不是列表中Subclass的实例。但为什么施放类是错误的? SubClass中的属性在投射后可以为null,我可以像上面的示例中那样将其设置为manualy。你对此有何感想? – 2013-04-04 04:27:44
我的意思是,铸造后SubClass应具有基类的所有属性,其余属性在SubClass中将为null – 2013-04-04 04:34:07
@ Rami.Q - 好的,您的意见向我澄清了一些关于您想要的东西。我修改了我的答案来解决这个问题。 – 2013-04-04 06:20:42
你似乎有很多的属性和设置他们都没有简单的方法的类。你现在遇到了一个问题,你需要一个具有附加属性的类,但你必须处理基类的混乱。
我建议,而不是创建一个子类,铸造,创建丑围绕着一个包装类:
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将实现一个包装也可以实现一个接口,使包装推迟所有的呼叫到该实例已包裹。
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();
仅仅因为你有一个超类的参考并不意味着你指向一个超类。 'Base baseRef'可能指向SubClass1,因此'SubClass2 subRef =(SubClass2)baseRef'不是有效的强制转换。 – 2013-04-17 17:54:49
有一种方法:各种基于Java Bean规范的操作。
例如:
for(Base base: list){
SubClass sub = new SubClass();
PropertyUtilsBean.copyProperties(sub, base);
if(...){
sub.setSelected(true);
}
newList.add(sub);
}
这部作品根据同名获取/ setter方法。不复制内部字段。
如果您需要复制内部字段,使用javax.lang.reflect
其实并不难。
从超类初始化子类 - 为什么?这听起来有些不妥,最坏的情况是危险的。 – 2013-04-04 04:03:27
“列表 ”字段在哪里定义?在'Base'类中呢?你是否能够控制其声明的位置以及初始化位置? –
Perception
2013-04-04 04:05:04
我强烈建议你看看“宁愿组成比继承” - 谷歌它。你会发现一些有趣的讨论。我只是这样说,因为它看起来像你试图拼命滥用特权。 – 2013-04-04 04:10:34