2017-04-16 33 views
0

我是在Android開發中使用RetroLamda的新手。我已經瞭解到,它取決於參數類型來選擇方法。我有界面如下圖所示:Android RetroLamda執行概率

interface OnCallListener { 
    onSuccess(String msg); 
    onError(String msg); 
} 

現在常見的實現:

test.SetOnCallListener(new OncallListener(){ 
    public void onSuccess(String msg){ 
    ...... 
    } 
    public void onError(String msg){ 
    ..... 
    } 

}); 

如何RetroLamda表達式處理這種類型的其中兩個方法有相同的輸入型病例嗎?

+1

不應該這是一個無效的lambda,因爲它有多個抽象方法?我錯過了有關retrolambda的事情嗎? –

+0

請立即檢查問題,@ M.Prokhorov –

回答

2

簡短的回答

您可以使用默認的方法和繼承你的聽衆是隻負責一個類型的事件。

龍回答

我給的答案是更適合遷移而承受類似品質的普通Java偵聽器:那些具有多個抽象方法,偶爾那些將包含樣板不必要的數額,以及接口,因爲用戶只會對處理一個特定事件感興趣,而不是一次處理所有事件。

與Retrolambda一起使用它們會帶來一些您可能會或可能不會願意採取的折衷。更多關於這個herehere

基本思想:使監聽器參數成爲用lambda實現的有效目標,必須確保無論監聽器目標類是什麼,它都應該有一個且只有一個抽象方法。 考慮初始類:

public interface CallListener<T> { 
    void onSuccess(T result); 
    void onError(String errorMsg); 
} 

它有幾個抽象方法,所以,使其成爲拉姆達有效分配的目標,我們以「貫徹」所有,但一個方法。我們使用默認的方式做到這一點:

public class CallListeners { 
    public static interface SuccessListener<T> extends CallListener<T> { 
    // we implement onError in such way that listener would ignore error event 
    default void onError(String _ignore) {} 
    } 
    public static interface ErrorListener<T> extends CallListener<T> { 
    default void onSuccess(T result) {} 
    } 

    // Methods to "help" compiler infer correct listener type 
    public void <T> Call<T> success(SuccessListener<T> listener) { 
    return listener; 
    } 
    public void <T> Call<T> error(ErrorListener<T> listener) { 
    return listener; 
    } 
} 

之後,就可以使用上面所有這樣的:

test.SetOnCallListener(
    CallListeners.success(argument -> /*your implementation here*/)); 

或者

你可以做一個具體的類允許插入其方法的各種(可能可重用的)實現,並且具有工具工廠方法,其中除了一個事件監聽器之外的所有事件監聽器都通過空操作來實現:

public class CallListenerImpl<T> implements CallListener<T> { 
    private Consumer<T> success; // java.util.function.Consumer 
    private Consumer<String> error; 
    public CallListenerImpl(Consumer<? super T> succ, Consumer<String> err) { 
    success = succ; error = err; 
    } 
    void onSuccess(T result) { 
    success.accept(result); 
    } 
    void onError(String err) { 
    error.accept(err); 
    } 

    // Sugary stuffs: 
    public static <T> CallListenerImpl<T> success(Consumer<T> succ) { 
    return new CallListenerImpl<>(succ, noOp()); 
    } 
    public static <T> CallListenerImpl<T> error(Consumer<String> err) { 
    return new CallListenerImpl<>(noOp(), err); 
    } 
    private static <T> Consumer<T> noOp() { 
    return a -> {}; 
    } 
}