2017-10-12 164 views
0

說我有以下設置:返回集合

abstract class AbstractBaseClass { 

    // Some common attributes 

    AbstractBaseClass() { } 

    AbstractBaseClass(AbstractBaseClass orig) { 
     // Copy ctor impl 
    } 

    protected abstract AbstractBaseClass clone(); 
} 

class DerivedClassA extends AbstractBaseClass { 

    // Some specialized attributes 

    DerivedClassA() { } 

    DerivedClassA(DerivedClassA orig) { 
     super(orig); 
     // Copy ctor impl 
    } 

    List<DerivedClassB> subObjects = new ArrayList<>(); 

    protected DerivedClassA clone() { 
     return new DerivedClassA(this); 
    } 

} 

class DerivedClassB extends AbstractBaseClass { 

    // Some specialized attributes 

    DerivedClassB() { } 

    DerivedClassB(DerivedClassB orig) { 
     super(orig); 
     // Copy ctor impl 
    } 

    List<DerivedClassC> subObjects = new ArrayList<>(); 

    protected DerivedClassB clone() { 
     return new DerivedClassB(this); 
    } 

} 

// DerivedClassC implemented the same way 

現在,我想在我的抽象基類來實現一個通用的方法,它 克隆包含給定對象名單在派生類中的一個:

abstract class AbstractBaseClass { 

    // Other stuff, see above 

    // Doesn't work because of type issues 
    protected <T> List<T> cloneList(List<? extends AbstractBaseClass> origList) { 
     if (origList == null) return null; 

     List<T> result = new ArrayList<>(); 
     for (AbstractBaseClass i: origList) { 
      result.add(i.clone()); 
     } 

     return result; 
    } 
} 

現在我想調用這個方法如下:

class DerivedClassA extends AbstractBaseClass { 

    // Other stuff 

    List<DerivedClassB> subObjects; 

    DerivedClassA(DerivedClassA orig) { 
     super(orig); 
     // Copy ctor impl 
     subObjects = cloneList(orig.subObjects); 
    }   

} 

現在我期望的是AbstractBaseClass中的cloneList(...)的實現返回一個與參數列表類型相同的列表,所以我可以將它們存儲在我的派生類中。我會怎麼做呢?

我到目前爲止已經發現的是,我可以實現cloneList(...)像這樣:

protected List<AbstractBaseClass> cloneList(List<? extends AbstractBaseClass> origList) { 
    // null check... 

    List<AbstractBaseClass> result = new ArrayList<>(); 
    for (AbstractBaseClass i: origList) { 
     result.add(i.clone()); 
    } 

    return result; 
} 

,然後使用投射在我的派生類:

DerivedClassA(DerivedClassA orig) { 
    super(orig); 
    // Copy ctor impl 
    List<AbstractBaseClass> tmp = cloneList(orig.subObjects); 
    for (DerivedClassA i: tmp) { 
     subObjects.add((DerivedClassA) i); 
    } 
}  

但是,這是不是真的滿足我,因爲我想有一個通用的實現,不依靠鑄造後獲得我的克隆集合的類型AbstractBaseClass

+3

正如你想要的'通用'的實現,泛型可能值得一看 – Stultuske

+0

檢查此頁:https://docs.oracle.com/javase/tutorial/java/generics/index.html – 2017-10-12 13:34:56

+0

*請注意*「克隆設施遭受嚴重的設計缺陷「http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4220218 –

回答

0

您可以更改以下行:

abstract class AbstractBaseClass<T extends AbstractBaseClass<T>> 

protected List<T> cloneList(List<T> origList) { 
    if (origList == null) 
     return null; 

    List<T> result = new ArrayList<T>(); 
    for (T i : origList) { 
     result.add(i.clone()); 
    } 

    return result; 
} 

和派生類

class DerivedClassA extends AbstractBaseClass<DerivedClassA> 

DerivedClassA(DerivedClassA orig) { 
    super(orig); 

    List<DerivedClassA> clonedList = cloneList(orig.subObjects); 
    subObjects.addAll(clonedList); 
} 

在你不需要到最後投下任何東西