簡體   English   中英

java,從SuperClass初始化SubClass

[英]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(s​​ence 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規范的操作。

例如:

Commons BeanUtils

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM