2015-07-10 24 views
11

jenerik uzanır ClassB ve T oluştururken çıkarsama mı? Bu istediğiniz cevaptır ama kesinlikle en basit versiyonu okur eğerİçiçe Üç sınıfları

new ClassB<ClassA<ClassR>, ClassR>() 
+0

Yan not: Konu uzatmak için daha Runnable uygulamak daha iyidir. – m0skit0

+0

, bir fark yaratmadığından ClassR olarak değiştirildi – Nutel

+1

Lütfen E – Al1en313

cevap

0

emin değil:

new ClassB<ClassA<ClassR>>() 

yerine: Örneğin, kullanımı uygun olur

class ClassR { 
} 

class ClassA<T extends ClassR> { 
} 

class ClassB<T extends ClassR> extends ClassA<T> { 

    void foo(T bar) { 
    } 
} 

public void test() { 
    ClassB<ClassR> classB = new ClassB<>(); 
} 
+0

Benim kötüyüm, E ve T'yi ClassB'nin içinde kullanıyorum, hala E'nin bir yolu var mı? (soruları güncelledi) – Nutel

1

Bu daha da basit bir yaklaşım sizin için işe yarayabilir:

class ClassR {} 
class ClassA<T extends ClassR>{}  

class ClassB<T extends ClassR> extends ClassA<T> { 
    void foo(T bar) { 
    } 

    void bar(ClassA<T> param) { 
    } 
} 

Ve kullanım sonra ClassA yapılan herhangi bir atıf olmaya atlar: güvenle onun bildiriminde ClassA türü parametresi atlayabilirsiniz ClassA tip E gibi

class SubR extends ClassR {} 

ClassB<SubR> obj = new ClassB<SubR>(); 
+0

Bence bu iyi bir cevap. Gösterilen koddan bakıldığında, 'E' asla ClassB'deki bir yöntemden döndürülmez. Ancak, ClassB'de (örneğin, 'bar' yönteminde) siz (derleyici) sadece bunun bir ClassA olarak görülebilecek bir şey olduğunu bilirsiniz. Bu nedenle sadece ClassA ve T'den mthod'ları güvenli bir şekilde kullanabilirsiniz. Bu nedenle 'E' tipi parametresine gerek yoktur. Ancak, 'E' yöntemlerini çağrıştıran bir ClassB örneğine referansla kod varsa, gerçekten farklı şeyler vardır. – Sebastian

0

uzanır.
Uygun ClassA type parametresi, ikinci parametrede ClassB'a zorlanır.
gösterim amacıyla kod aşağıda verilmiştir:

class ClassB<E extends ClassA, T extends ClassR> extends ClassA<T> { 

    private ClassA ob; 

    public ClassB(E e, T t) { 
    super(t); 
    ob = e; 
    } 

} 

Kullanım örneği:

class ClassR { 
    public ClassR() {}; 
} 

class ClassS extends ClassR { 
    private int x; 
    public ClassS(int x) { 
    super(); 
    this.x = x; 
    } 
} 

public static void test() { 
    ClassS data1 = new ClassS(1); 
    ClassB <ClassB, ClassS> first = new ClassB<>(null, data1); 
    ClassS data2 = new ClassS(2); 
    ClassB <ClassB, ClassS> second = new ClassB<>(first, data2); 
} 
+0

Bu çözümle ClassA sınıfından miras alırken ClassA'yı rawtype olarak alırsınız. 'E ClassA' 'da ClassA'dan jenerik tip hakkında bilgiye ihtiyacınız olduğunda, kaybolursunuz. Yukarıda belirtildiği gibi, gösterilen kodun örtük gereksinimler gibi kokması nedeniyle iyi bir uygulama sunmamızı engelleyen bazı tasarım kusurlarının olduğunu düşünüyorum. – Sebastian