2010-03-30 10 views
8

Bu konuyla ilgili farklı sorular gördüm, ancak bu konuyu çok kafa karıştırıcı buluyorum. O olduğu içinJava Generics isim çatışması, yöntem doğru şekilde geçersiz kılındı ​​

yapmak istediğim tüm, bir arabirim uygulayan bir soyut sınıf var ve sabit sınıf getKommune() ve setKommune(Kommune kommune), ancak diğer yöntem uygulaması gerekmektedir, böylece bu soyut sınıf uzanan bir sınıf var olduğunu soyut sınıf.

Aşağıdaki arabirim var.

public interface KommuneFilter { 

    <E extends AbstractKommune<?>> void addKommuneFromCurrentUser(E e); 

    Kommune getKommune(); 

    void setKommune(Kommune kommune); 
} 

Ve bu Özet sınıf

public abstract class AbstractKommune<E extends AbstractKommune<?>> implements KommuneFilter { 
    @PrePersist 
    void addKommuneFromCurrentUser(E e) { 
      Kommune k = e.getKommune(); 
    } 
} 

Ve ben, ben

Name clash: The method of has the same erasure of type but does not override it

olsun Ancak bu

public class Person extends AbstractKommune<Person> { 
     private Kommune kommune;    
     public void setKommune(Kommune kommune) {this.kommune=kommune;} 
     public Kommune getKommune() {return kommune;} 
    } 

gibi kullanmak istiyorum Neden doğru geçersiz değil?

public interface KommuneFilter<E extends AbstractKommune<?>> { 
    public void addKommuneFromCurrentUser(E e); 
} 

public abstract class AbstractKommune<E extends AbstractKommune<?>> implements KommuneFilter<E> 

public class Person extends AbstractKommune<Person> 

cevap

4

Doğrusu sadece yönteminden daha, arayüz jenerik yapma öneririm::

interface KommuneFilter<E extends AbstractKommune<?>> { .. } 

Ve @Bozho için

GÜNCELLEME

sayesinde çözüm şudur sonra

public abstract class AbstractKommune<E extends AbstractKommune<?>> 
    implements KommuneFilter<E> 
+0

Teşekkür ederim, bu işe yarar görünüyordu. Ancak, belki de bu çözümün neden işe yarayıp yaramadığını anlamış olabilirsiniz. –

+0

@Shervin: çünkü orijinal tasarımınızda, arabirim tarafından belirtilen yöntem genel bir yöntemdir ve soyut sınıfınızın '@ Geçersiz Kıl 'girişimi bir değil. – polygenelubricants

2

Bunun bir isim çatışmasının sebebi ve bir geçersiz kılma değil nedeni. Arabirim tarafından belirtilen yöntem genel bir yöntemdir; soyut sınıfınızın bunu geçersiz kılma girişimi değildir. Sorununuzu çoğalır

Daha özlü kod şudur:

interface I { 
    <E> void foo(E e); 
} 

class C<E> implements I { 
    public void foo(E e) { // name clash at compile time! 
    } 
} 

Buradaki sorun interface I, uygulamacılarıdır genel bir yöntem <E>foo (o vb bir <Integer>foo, <Boolean>foo olabilir) sağlamak gerektiğini belirtir ama Yani, C<String> gerçekten sadece foo(String)'a sahiptir. Bunu düzeltmek için

bir yolu düzgün @Override için, C.foo genel bir yöntem yapmaktır interface I jenerik yöntemi:

interface I { 
    <E> void foo(E e); 
} 

class C<E> implements I { 
    @Override public <T> void foo(T t) { 
    } 

    public static void main(String args[]) { 
     C<String> o = new C<String>(); 
     o.<Integer>foo(0); 
     o.<Boolean>foo(false); 
    } 
} 

Bu yukarıdaki kodda ne yaptığını görebilirsiniz: Eğer genel bir türü var C<E> jenerik bir yöntem <T>foo (T yerine E'u kullanabilirsiniz, ancak bu hiçbir şeyi değiştirmez - yine de kendi tür parametresiyle genel bir yöntemdir). interface Iinterface I da belirtildiği gibi C<String> da <Integer>foo, vb.

bu sonra muhtemelen yerine interface I<E> jenerik yapmak istiyorum, size gereken bir şey değilse:

Şimdi
interface I<E> { 
    void foo(E e); 
} 

class C<E> implements I<E> { 
    @Override public void foo(E e) { 
    } 
} 

tipi ve yöntem hisseleri aynı tip parametre (örneğin bir I<Boolean> sadece foo(Boolean) sahiptir , bir C<String> sadece bir foo(String)) sahiptir;

+0

, sorun '@ Geçersiz Kıl 'notu değil. Yapman gereken şey, jenerik parametreyi, yöntemde aynı ada sahip başka bir tanıtımı tanıtarak sınıftan gizlemektir. (Eclipse, "E parametresi E tipini gizliyor" verir) – Bozho

+0

Tarihsel olarak, kendimi (ve başkalarının) her zaman notu kullanmasını hatırlatmak için her zaman "geçersiz kıl" yerine "Geçersiz Kıl" yazarım. Burada karışıklığa neden olduğunu anlıyorum. Şimdi daha net olmalı. Saklanma kısmı hakkında haklısınız; Bence kişisel olarak büyük bir anlaşma değil. – polygenelubricants

+1

metodu için 'E' yerine' T' kullanıldığında daha iyi olurdu, ancak bütün "tasarım" hala yanlış geliyor. – Bozho

İlgili konular