2013-08-26 20 views
7

我想創建這兩個類的通用接口,但我不知道如何以正確的方式指定泛型。創建通用接口限於自己的類

public class ThingA implements Thing { 
    public ThingA createCopy(ThingA original); 
} 

public class ThingB implements Thing { 
    public ThingB createCopy(ThingB original); 
} 

我試過了。

public interface Thing<V extends Thing<V>> { 
    public V createCopy(V original); 

} 

但我仍然可以做這樣的事情,這是不應該被允許的。

public class ThingB implements Thing<ThingA> { 
    public ThingA createCopy(ThingA original); 
} 

回答

6

沒有this關鍵字泛型(也不適用於方法參數和返回值聲明),因此您不能完全按照您的要求進行操作。

換句話說,接口將允許確保類中的所有方法使用一致的類型,但不能引用類類型本身。

0

您是否在尋找

public interface Thing<V> { 
    public V createCopy(V original); 
} 

?如果不是,你能否更詳細地解釋一下「爲兩個類創建通用接口」對你意味着什麼?

+1

這仍然可以讓他做到他不想做的事。泛型不會阻止您僅使用一種類型的類,因爲這將與泛型相反。 – giorashc

1

這是不可能的。這不是泛型的用途。泛型適用於型安全,即避免鑄造。如果某人制作了一個ThingB類,以某種方式實現Thing<ThingA>,那麼很好。這是完全類型安全的。你爲什麼在乎?它如何妨礙你在做什麼?

0

如果您可以自由使用擴展,而不是執行,那麼你可以做的是這樣的:

public interface Thing { ... } 
public abstract class Copyable { 
    public final Copyable copy() { 
     Copyable clone = createCopy(); 
     if (clone.getClass() != getClass()) 
      throw new RuntimeException("Copy has wrong type!"); 
     return clone; 
    } 
    protected abstract Copyable createCopy(); 
} 

,然後用它喜歡:

public class Test extends Copyable implements Thing { 
    public String content = null; 

    @Override 
    public Copyable createCopy() { 
     Test clone = new Test(); 
     clone.content = this.content; 
     return clone; 
    } 
} 

/*code somewhere*/ { 
    Test t1 = new Test(); 
    t1.content = "Hello world!"; 
    Test t2 = (Test)t1.copy(); 
    System.out.println(t2.content); 
} 

一個這樣的問題,是那Copyable不是一個接口。但是,如示例中所示,可以毫不費力地使用此類語句,但語言級別不支持使用的類檢查。換句話說,createCopy抽象方法並不侷限於它所複製的類,所有這一切都取決於擴展類的程序員或擴展它的類。

積極的一面是,如果您在對象上調用.copy(),它必須返回一個與它自己相同的對象。如果您願意,您可以返回null而不是例外情況。然後你得到好或沒有

但是,老實說,我不是很懂,爲什麼你的createCopy本地方法有一個參數。 這可能是再一個靜態方法...... altrough我甚至無法想象會進入該代碼塊:

static <X extends Thing> X copy(X object) { ... } 

可能,你可以使用靜態泛型方法的初步實踐相結合,結果變得更友好一點:

public interface Thing extends Cloneable { 
    public static <X extends Thing> X copy(X thing) { 
     Object clone = thing.clone(); 
     if (clone.getClass() != getClass()) 
      throw new RuntimeException("Copy has wrong type!"); 
     return (X)clone; 
    } 
} 

public class ThingA implements Thing { 
    public Object clone() { ... } 
} 

/*code somewhere*/ { 
    ThingA a1 = new ThingA(); 
    ThingA a2 = Thing.copy(a1); 
} 

儘管如此,克隆方法是一個例外,而不是語言的限制規定,但我認爲這是目前最好的解決方案。