2016-06-15 32 views
0

下面的代碼正常工作:通用接口和協方差

public class ICopyableTest { 

    private interface ICopyable<T extends ICopyable<? extends T>> { 
     void copyFrom(T original); 
    } 

    private interface IVal<T> extends ICopyable<IVal<? extends T>> { 
     T getV(); 
    } 

    private static class Val<T> implements IVal<T> { 
     private T v; 

     public T getV() { 
      return v; 
     } 

     public Val(final T v) { 
      this.v = v; 
     } 

     @Override public void copyFrom(final IVal<? extends T> original) { 
      v = original.getV(); 
     } 
    } 

    private static class StrVal extends Val<String> { 
     public StrVal(final String v) { 
      super(v); 
     } 
    } 


    public static void main(String[] args) { 
     Val<Object> o1 = new Val<>(new Object()); 
     Val<String> o2 = new Val<>("qwe"); 

     StrVal o3 = new StrVal("zxc"); 

     o1.copyFrom(o2); // that's the point 
     o1.copyFrom(o3); 

     o2.copyFrom(o3); 
     o3.copyFrom(o2); 

     Val<Object> toObj = (Val<Object>) (Val<?>) o2; // [1] 
    } 
} 

基本上我有ICopyable接口與提供複製功能,IVAL這增加的值存儲的上方,並且其實現的Val兩個示例類。 <? extends T>的目的是爲CopyFrom方法提供協變參數,所以你可以做o1.copyFrom(o2)等 所以這一切工作正常,我猜。

現在比方說,我希望有另一個參數超過ICopyable或IVAL類:

private static class Bla<T extends ICopyable<T>> { 
    final T value1; 
    final T value2; 

    public Bla(final T value1, final T value2) { 
     this.value1 = value1; 
     this.value2 = value2; 
    } 

    void letsCopy() { 
     value1.copyFrom(value2); 
     value2.copyFrom(value1); 
    } 
} 

現在我爲什麼不能與下列任何實例呢?

new Bla<StrVal>(o3, o3); 
new Bla<Val<Object>>(o1, o1); 
new Bla<Val<String>>(o2, o2); 

說實話,我在這裏有點失落,這就是爲什麼我正在探索它。還有一個單獨的非常重要的問題,即爲什麼使用泛型是爲了消耗時間,甚至在使用java工作5年以上後,如果沒有半小時冥想,我無法弄清楚這些事情 - 我只是啞巴?

我只想要一個參數化的類,它允許我使用IVal/ICopyable值,注意它應該是參數化類,而不是單個方法,因此可以將這些值的實例存儲在字段中,例如。

+0

閱讀,這是令人困惑的。我認爲你已經完成了你想要做的事情。你試圖完成的最簡單的形式是什麼,你的抽象目標/想法是什麼? – Underbalanced

+0

我的最終目標幾乎是我在最後一段中寫的,所以以正確的方式實現Bla類。在這個例子中,班級當然沒有做任何過於實際的事情,但這僅僅是一個例子 - 它只是一個普通的「處理」班,它應該接收IVal 或IVal 例如,並與他們做一些事情(例如讓我們使用複製方法)。對不起,它令人困惑,我無法理解無關的問題,所以我不知道如何提出正確的問題。我會很高興,如果有人可以解釋我爲什麼我不能實例化Bla這樣的... – Eugene

+0

嘿@Underbalanced抱歉,如果我以任何方式讓你心煩,但是imo沒有理由刪除你的答案: -/ – Eugene

回答

0

我會做的是這樣

public class Test { 

    interface Copyable<T> { 
     void copyFrom(Copyable<T> v); 
     T getV(); 
    } 

    interface Val<T> extends Copyable<T> { 
     // Do not know if this is usefull 
    } 

    abstract class AbstractVal<T> implements Val<T> { 
     T value; 
     public AbstractVal(T val) { 
      this.value = val; 
     } 
    } 

    class StrVal extends AbstractVal<String> { 

     public StrVal(String o3) { 
      super(o3); 
     } 

     @Override 
     public void copyFrom(Copyable<String> v) { 
      this.value = v.getV(); 
     } 

     @Override 
     public String getV() { 
      return this.value; 
     } 
    } 

    class Bla<T extends AbstractVal<S>, S> { 
     final T value1; 
     final T value2; 

     public Bla(T value1, final T value2) { 
      this.value1 = value1; 
      this.value2 = value2; 
     } 

     void letsCopy() { 
      value1.copyFrom(value2); 
     } 
    } 

    void test() { 
     StrVal o1 = new StrVal("qwe"); 
     StrVal o2 = new StrVal("qwe2"); 
     StrVal o3 = new StrVal("zxc"); 
     Bla tester = new Bla<StrVal, String>(o1, o2); 
     tester.letsCopy(); 
     System.out.println(tester.value1.getV()); 
    } 

    public static void main(String[] args) { 
     Test t = new Test(); 
     t.test(); 
    } 
} 

也許有點複雜,它在做什麼,但我認爲它的想法..

+0

這很有趣,所以在你的代碼和我的代碼中,明確定義S實際工作的技巧',S>'。非常感謝您的回答,我會盡力處理。你知道,如果有其他方式可以表達這一點,它只是不對,不是嗎? – Eugene