[英]java, initialize SubClass from SuperClass
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);
}
我試圖避免將基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;
之后,Object sub
應具有Object b
的Attribute Name, title
Attribute為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
,並使用成分代替 。
編輯根據您的評論,聽起來您想要使用Base
實例列表作為開始構建SubClass
實例列表。 一種方法是為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規范的操作。
例如:
for( Base base: list ){
SubClass sub = new SubClass();
PropertyUtilsBean.copyProperties( sub, base );
if(...){
sub.setSelected(true);
}
newList.add(sub);
}
這基於同名的get / setters。 不復制內部字段。
如果您需要復制內部字段,實際上使用javax.lang.reflect
實現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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.