2017-08-29 59 views
1

我正在爲Java創建一個小型庫,並且其中一部分API是一個帶有3個參數的函數接口(因此,lambda表達式)。我意識到他們中的兩個可能經常是不需要的。因此,我認爲做這樣的事情:Java爲什麼我不能使用具有功能接口的多重繼承

class Main { 

    public static void main(String[] args) { 
    call((s) -> System.out.println(s)); 
    } 

    static void call(A a) { 
    a.call(7, 42, "Hello World!"); 
    } 

    static interface A { 

    void call(int x, int y, String s); 

    } 

    static interface B extends A { 

    void call(String s); 

    default void call(int x, int y, String s) { 
     call(s); 
    } 

    } 

} 

我預計,用戶可以再插入前兩個參數,如果他們想,但如果他們沒能離開他們了,他們會被忽略。但是,當我試圖編譯上面的代碼時,我得到了一個編譯時異常,消息是「不兼容的類型:lambda表達式中的不兼容參數類型」。爲什麼這不起作用?

+0

如果你只是[將lambda轉換爲'(B)'](https://ideone.com/AO1KKo),那麼你的代碼工作正常。否則,它只是假設你正在創建一個只實現'A'的對象。 – 4castle

回答

1

您的static void call(A a)方法需要A類型的參數或滿足您在其上定義的SAM method簽名的lambda表達式。這就是爲什麼它會抱怨說,你只是過客1個參數時,它實際上是期待3.如果你想傳遞類型的lambda表達式B必須先投這樣的:

call((B)(s) -> System.out.println(s)); 

,也可以編輯您的static void call方法來接受B類型的參數。

1

call(A a)需要接口A的實例作爲參數,並在界面A方法調用的方法是服用3個參數:void call(int x, int y, String s);所以看起來要聲明的參數作爲接口的B一個實例 - 不A

因此修改:

static void call(A a) { 
    a.call(7, 42, "Hello World!"); 
} 

到:

static void call(B b) { 
    b.call(7, 42, "Hello World!"); 
} 

將解決問題

相關問題