2013-08-23 6 views
8

Ben nesneler kendi kopyalarını yapabilirsiniz sağlayan bir arayüz:Altsınıflar

public interface Duplicable<T extends Duplicable<T>> { 
    public T duplicate(); 
} 

Şimdi

class X implements Duplicable<X> 

var ama aynı zamanda X.

genişleten bir sınıf Y sahip

Başka bir genel sınıfa gerek duymadan, bu bir sorun değil:

public class DoStuffWithDuplicable<T extends Duplicable<T>> 

Ben yüzden

public class DoStuffWithDuplicable<T extends Duplicable<? super T>> 

çalıştı

X. onu devralır beri Duplicable<Y> ama Duplicable<X> uygulamıyor beri Y kullanarak DoStuffWithDuplicable genel bir sürümünü kullanın .. ama bu araçlar Daha sonra kod gövdesinde güvenli olmayan bir dökümün

. Ayrıca, sınıf parametreleri daha kıvrımlıdır ve sınıfın kullanımını anlamak daha da zorlaşır. Bu problemin nasıl geçeceği hakkında bir fikrin var mı?

+0

bu ifadeleri Can:

bir diğer seçenek kütüphanede güvensiz yayınları kullanmanızı ve elle türlerini kontrol etmek olurdu Yinelenebilir'i değil, X'i miras aldığından çoğaltılamaz. " ? – tbsalling

+0

Üzgünüz, biçimlendirme problemi – phil

+1

Bir not olarak, bu, bazı bilgisayar bilimcilarının tüm sınıfların ya “soyut” ya da “final” olması gerektiğini söylemesinin tam bir nedenidir. Sen de 'equals' ile sorunlara koşacaksın; somutlaşabilir bir "X" olanı ortadan kaldırmak için belki refactor olabilir misiniz? – chrylis

cevap

1

Sorunuzu düzgün bir şekilde anlayamamış olabilirim, ancak bir adım atacağım.

Her şeyden önce, neden kendini böyle genişleten bir arayüzünüz var? Eğer jenerik parametre dublike olmak istiyorum başka bir sınıf kullandığınızda, böyle yapmak Ardından

public interface Duplicable<T> { 
    public T duplicate(); 
} 

:

public class X<T extends Duplicable<T>> { 
    code... 
} 

Şimdi sizi

Ne deneyebileceğiniz şudur X'den miras almamalı, alt sınıflardaki herhangi bir jenerik bileşen Duplicable olmalıdır.

+1

Ben "neden" düşünmek oldukça açık: OP, T'yi onu uygulayan sınıfla aynı tipte sınırlamak istiyor. Sizin yolunuz, örneğin, "Tamsayı", " Duplicable" öğesinin uygulanmasına izin verir. –

+0

@MarkoTopolnik: 1) Ancak OP'nin kısıtlaması onu kısıtlamıyor. Onu kısıtlamak mümkün değil. 2) OP'nin kısıtlaması herhangi bir tip-güvenlik amacına hizmet etmiyor. Arayüz, olduğu gibi güvenlidir. – newacct

+0

'>' sınırlarını genişletir; 'T',' Enum', type parametresini kısıtlar: 'Enum >' dizinini genişletir. “E” enum sınıfının kendisi olmalı. –

1

Bunu Java'da yapmak mümkün değildir.

Y. tipindeki bir nesnedeki object.duplicate() yöntemini çağırdığınızı varsayalım. Daha sonra, Y, Duplicate <X> uyguladığı için, tip sistemi yalnızca X türünde bir nesne döndüreceğinden emin olabilir.

Ancak bir DoStuffWithDuplicable <X> oluşturabilir ve Y nesnelerini ona geçirebilirsiniz.

DoStuffWithDuplicable<X> blub = new DoStuffWithDuplicable<X>(); 
    Y y = (Y) blub.doStuff(new Y()); 

Geri dönüş değerleri için, kütüphanenizin istemcisi, muhtemelen beton türlerini bildiği için güvenli kalıpları kullanabilir. öyle beri, "Ben Y kullanarak DoStuffWithDuplicable genel bir sürümünü kullanamazsınız:

class DoStuffWithDuplicable<T extends Duplicable<? super T>> { 
    T doStuff(T obj) { 
     @SuppressWarnings("unchecked") 
     T t = (T) obj.duplicate(); 
     if (!t.getClass().equals(obj.getClass())) 
      throw new ClassCastException("..."); 
     return t; 
    } 
}