2009-03-06 24 views

cevap

16

Bunlardan birine sahip olduğunuzda yapabilecekleriniz açısından pratik bir fark yoktur, çünkü tip parametresi sadece "çıkış" konumunda kullanılır. Diğer yandan, 'u'dan biri olarak kullanabilmeniz açısından büyük bir fark var.

Bir Enumeration<JarEntry> aldığınızı varsayalım - bunu, Enumeration<ZipEntry> argümanlarından biri olarak kabul eden bir yönteme aktaramadınız. Siz , Enumeration<? extends ZipEntry> alarak bir yönteme geçebilirsiniz.

En belirgin örnek olan List<T> hem giriş hem de çıkış konumlarında type parametresini kullanan bir türünüz olduğunda daha ilginçtir. Bir parametrede varyasyonlara sahip üç yöntem örneği. Her durumda, listeden bir öğe almaya çalışacağız ve başka bir tane ekleyeceğiz.

// Very strict - only a genuine List<T> will do 
public void Foo(List<T> list) 
{ 
    T element = list.get(0); // Valid 
    list.add(element); // Valid 
} 

// Lax in one way: allows any List that's a List of a type 
// derived from T. 
public void Foo(List<? extends T> list) 
{ 
    T element = list.get(0); // Valid 
    // Invalid - this could be a list of a different type. 
    // We don't want to add an Object to a List<String> 
    list.add(element); 
} 

// Lax in the other way: allows any List that's a List of a type 
// upwards in T's inheritance hierarchy 
public void Foo(List<? super T> list) 
{ 
    // Invalid - we could be asking a List<Object> for a String. 
    T element = list.get(0); 
    // Valid (assuming we get the element from somewhere) 
    // the list must accept a new element of type T 
    list.add(element); 
} 

Daha fazla ayrıntı için okuyun:

+0

JarEntry (ZipFile.entries joker kullanıyorsa neden nedeni) gibi bir ZipEntrySubclass? –

+0

Teşekkür Tom - Bu, bu hafta Jon Skeet Benden önce bir cevap aldı ikinci kez benim cevap :) –

4

Evet, düz sun generics tutorials birinden:

Şekil, üç alt sınıf ile soyut bir sınıftır: Daire, Dikdörtgen, ve Üçgen.

public void draw(List<Shape> shape) { 
    for(Shape s: shape) { 
    s.draw(this); 
    } 
} 

Bu beraberlik() yöntem yalnızca Shape listelerinde çağrılabilir ve bir listede adı verilen olamaz fazlalaştı örneğin Circle, Dikdörtgen ve Üçgeni'nin . yöntemini sahip olmak için aşağıdaki gibi yazılı olmalı, şekil her türlü kabul ediyoruz: Şimdi

public void draw(List<? extends Shape> shape) { 
    // rest of the code is the same 
} 
+0

düzenler. Skeeting olarak adlandırdığımızı öneriyorum. – GaryF

+0

iyi geliyor. geçmiş zaman ne olurdu? Sket? "Jon Skeet bana TEKRARLI!" :) – Epaga

+0

http://stackoverflow.com/questions/305223/jon-skeet-facts/317486#317486 –

0

sadece gittin ve ben C# dünyada üzerinde olsaydı şey hatırlattı . Logic and its application to Collections.Generic and inheritance

bir seçim olan şunlardır:

İlgili konular