2017-08-29 11 views
1

私はJava用の小さなライブラリを作っていましたが、APIの一部は3つの引数をとった機能的なインターフェイス(したがってラムダ式)でした。私はそれらの2つがしばしば望ましくないかもしれないことに気づいた。だから私はこのような何かを作るために考えた: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); 
    } 

    } 

} 

私は、彼らが望んでいた場合、ユーザーは、最初の2つのパラメータを挿入することもできますが、彼らはしなかった場合、彼らはそれらを残すことができると、彼らは無視されるだろうと予想しました。しかし、上記のコードをコンパイルしようとすると、コンパイル時に "互換性のない型:ラムダ式の互換性のないパラメータ型"というメッセージが出ます。なぜこれは機能しませんか?

+0

[ラムダを '(B)'](https://ideone.com/AO1KKo)にキャストすればコードは正常に動作します。それ以外の場合は、 'A'だけを実装するオブジェクトを作成していると仮定します。 – 4castle

答えて

1

static void call(A a)メソッドには、Aタイプのパラメータ、または定義したSAM methodシグネチャを満たすラムダ式が必要です。

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

またはあなたを編集することができます:あなたが最初のようにそれをキャストする必要がありBタイプのラムダ式を渡したい場合は、それが実際に3を期待しているときに、ちょうど1つのパラメータを渡していると文句を言うだろう理由ですstatic void callBのパラメータを受け入れる方法。

1

引数としてインタフェースAのインスタンスを受け取り、インタフェースAでメソッド呼び出しは3つの引数を取っているcall(A a)方法: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!"); 
} 

は問題を解決します

関連する問題