2013-08-03 16 views
12

Bunu açıklamak zor, ama her yere baktım ve iyi bir cevap bulamadım.Geçerli sınıfın türüne nasıl başvurabilirim?

Ben de yığın taşması sorular How can I refer to the class type a interface is implementing in Java? ve How do I return an instance of an object of the same type as the class passed in using Java 6?gördük ancak sorumun cevabını olamazdı. Miras uygularken bir istisna var. bir örnek vardır

, daha kolay anlaşılması için:

public interface SelfMaker <SELF>{ 
    public SELF getSelf(); 
} 

Ve A başka köpeklerle üreme bir Köpek var:

en Bazı arayüz denilen SelfMaker var diyelim. Yani köpek böyle bir "SelfMaker" dir:

public class Dog implements SelfMaker<Dog> { 
    String color; 

    public String toString() { 
     return "some " + color + " dog"; 
    } 

    public Dog procreate(Dog anotherDog) { 
     Dog son = getSelf(); 
     son.color = color; 
     return son; 
    } 

    @Override 
    public Dog getSelf() { 
     return new Dog(); 
    } 
} 

Ama sonra, bir köpek olan bir DomesticDog var ama onu adında güzel bir ailesi var. Şunun gibi:

Şimdi, "SelfMaker" ler olan şeylerden çiftler kolları bazı sınıf var
public class DomesticDog extends Dog { 
    private String name; 

    public String toString() { 
     return super.toString() + " named " + name; 
    } 
} 

, hadi bu sınıf "Çift" diyelim. Şunun gibi:

public class Couple<T extends SelfMaker<T>> { 
    private T first; 
    private T second; 

    public String toString() { 
     return first.toString() + " and " + second.toString(); 
    } 
} 

İSTİSNA: Ben DomesticDog s birkaç oluşturmak istediğinizde

istisna geliyor. Bu <DomesticDog> şikayet üzerine bir istisna durumu

public class CoupleOfDomesticDogs extends Couple<DomesticDog>{ 
    public DomesticDog procreate(){ 
     DomesticDog son = first.procreate(second); 
     return son; 
    } 
} 

: Bunun gibi Bound mismatch: The type DomesticDog is not a valid substitute for the bounded parameter <T extends SelfMaker<T>> of the type Couple<T>

Zaten bu sınıf Çift den genelleştirilmiş değişkeni değiştirmeye çalıştık: Couple<T extends SelfMaker<?>> ama "oğul" bir olmayacak DomesticDog (ve ben "oğlu" bir DomesticDog olmak istiyorum). Bir miktar döküm eklerseniz, derler, ancak daha az okunaklı olacaktır.

Yani ... işte soru şu: Bu, dökümler ve genellemeler olmadan bunu başarmanın bir yolu var mı?

+0

: Dog Her tip sonra parametre olarak kendileriyle bu uygulaması gerekecektir sorular/7354740/-sürekli-türü-a-type-variable-type-a-yol-için-yol) –

+0

Geçerli sınıfın sınıfı this.getClass() 'dir. Sınıf adı this.getClass(). GetName() 'dir. Bu kadar iyi. Ayrıca Java'da bir cast'i dinamik olarak belirtmenin bir yolu yoktur. –

cevap

7

Bunu döküm yapmadan yapmak için düşünmem mümkün değil. Size,

public class DomesticDog extends Dog { 
    private String name; 

    public DomesticDog procreate(Dog anotherDog) { 
     return (DomesticDog)super.procreate(anotherDog); 
    } 

    public Dog getSelf() { 
     return new DomesticDog(); 
    } 

    public String toString() { 
     return super.toString() + " named " + name; 
    } 
} 

public class Couple<T extends SelfMaker<? super T>> { 
    protected T first; 
    protected T second; 

    public String toString() { 
     return first.toString() + " and " + second.toString(); 
    } 
} 

Eğer Köpek her alt sınıfta getSelf() geçersiz kılmak istemiyorsanız: Eğer DomesticDog ait üreme ve getSelf yöntemleri geçersiz kılmak ve bu şekilde sınıf Çift ilanını değiştirirseniz Sorununuz çözülecektir sınıf Köpek aşağıdaki değişikliği yapabilir:

public Dog getSelf() { 
    Class<? extends Dog> thisClass = this.getClass(); 
    try { 
     return thisClass.newInstance(); 
    } catch (InstantiationException e) { 
    } catch (IllegalAccessException e) { 
    } 
    throw new UnsupportedOperationException(thisClass 
         + " does not supply a public no-arg constructor"); 
} 

Bu getSelf tarafından döndürülen her değer() this.getClass() örneğidir olduğunu garanti eder. Ama yine de, alt sınıflar için procreate() öğesinin dönüş değerini döndürmeniz gerekir. this.getClass() olarak bir dönüş türünü açıkça belirtmenin bir yolu yoktur.

+0

oldukça zekice. Ama ... sınıfın türüne atıfta bulunmanın bir yolu yok mu? Bu benim kod yolu daha uygun hale getirecektir – Bengalaa

+2

Nope, açıkça joker ya da döküm kullanmıyorsanız, jeneriklerle "this" runtime sınıfına başvuramazsınız. Yukarıdaki düzenlemeye bakın. –

+0

Bu fikirlerin tümü, tip sistemini atlatır ve derleyiciyi kontrol edemeden doğru şeyi yapmak için programlayıcıya güvenir. – newacct

0

getSelf() sonucunu belirten bir tür parametresiyle Dog jenerik ve soyut yapmalısınız.[Bir tür değişkenle akım tipine başvurmak için bir yolu var mı?] (Http://stackoverflow.com/: related

public abstract class Dog<T> implements SelfMaker<T> { 
    String color; 

    public String toString() { 
     return "some " + color + " dog"; 
    } 

    public T procreate(T anotherDog) { 
     T son = getSelf(); 
     son.color = color; 
     return son; 
    } 

} 

public class DomesticDog extends Dog<DomesticDog> { 
    private String name; 

    public String toString() { 
     return super.toString() + " named " + name; 
    } 

    @Override 
    public DomesticDog getSelf() { 
     return new DomesticDog(); 
    } 
} 
+0

Peki ya Dog nesnesi yapmak istiyorsan? Ya da DomesticDog'ların bir alt kategorisini yapmak için DomesticDog'u genişletmek isterseniz ne yapardınız? –

İlgili konular