2016-08-10 19 views
14

en böyle bir kaç deneme arabirimleri/sınıfları var diyelim:Java'da jenerik olmayan bir arayüzün genel yöntemi neden uygulanabilir?

abstract class Plant { 
    public abstract String getName(); 
} 

interface Eatable { } 

class Apple extends Plant implements Eatable { 
    @Override 
    public String getName() { 
     return "Apple"; 
    } 
} 

class Rose extends Plant { 
    @Override 
    public String getName() { 
     return "Rose"; 
    } 
} 

interface Animal { 
    <T extends Plant & Eatable> void eat(T plant); 
} 

Sen Animal.eat kısıtlamaları ile genel bir yöntemdir görebilirsiniz. İyi derler

class Human implements Animal { 
    @Override 
    public void eat(Plant plant) { 
    } 
} 

: Artık böyle benim Human sınıf var. Human.eat'un Animal.eat'dan daha az kısıtlı olduğunu görebilirsiniz, çünkü Eatable arabirimi kaybolur.

S1: Derleyici neden bu tutarsızlıktan şikayet etmiyor?

S2: Plant için Plant&Eatablenotunu düşürdü derleyici için kabul edilebilir ise, eat(Object plant) üzerine şikayet neden?

+2

Hangi Java sürümünü kullanıyorsunuz. Eclipse içinde Java 1.8 kullanılması beklendiği gibi derleme zamanı hatası verir. Intellij IDEA'da – Codebender

+0

@Codebender Java8. –

+2

@Codebender Bunu derlemekle ilgili bir sorunum yok. https://ideone.com/7xUcZn – flakes

cevap

12

Lesson: Generics by Gilad Bracha onun

public static <T extends Object & Comparable<? super T>> T max(Collection<T> coll) 

göre bu sözdizimi T1 & T2 ... & Tn kullanılarak, bir tür parametresinin birden sınırları veren bir örneğidir. Birden çok bağına sahip bir tür değişkeni, sınırları içinde listelenen tüm türlerin bir alt türü olarak bilinir. Çoklu bir bağ kullanıldığında, numaralı belgede belirtilen ilk tür, tür değişkeninin silinmesi olarak kullanılır.

böylece örnek <T extends Plant & Eatable> void eat(T plant); bunu geçersiz olduğunda bu yüzden derleyici şikayet etmiyor void eat(Plant plant); için silinecektir

0
Eğer kısıt uygulanmasını koymak istersen

Ahmed cevap, bu arada, haklı Hayvan arayüzü, bu şekilde ilan etmelidir:

interface Animal<T extends Plant & Eatable> { 
    void eat(T plant); 
} 

Sonra, derleyici için en az sürpriz politikası kullanılarak olacaktır tip bilgi vermeden Hayvan arabirimini uygulaması halinde Bir Bitki tipi olarak T'yi çıkarır. Ancak gerekli tür bilgileri verirseniz, derleyici düzgün çalışır.

İlgili konular