2017-11-07 16 views
3

말은 나는 다음과 같은 인터페이스를 가지고 :@FunctionalInterface 상속

@FunctionalInterface 
public interface First { 
    int fun(int a); 
} 

및 다음 또한

@FunctionalInterface 
public interface Second extends First { 
    default int fun(int a) { fun(a, a); } 

    int fun(int a, int b); 
} 

내가 예를 들어, 내가 할 수있는 First 소요 어딘가에 방법이있는 경우 :

methodThatTakeFirst(val -> val + 1); 

하지만 Second을 전달할 수도 있습니다.

methodThatTakeFirst((v1, v2) -> v2 * v2); 

그러나이 유일한 작품이 같은 람다 캐스팅 경우 :

methodThatTakeFirst((Second) (v1, v2) -> v2 * v2); 

내 질문은 : 하위 인터페이스에 람다 캐스팅 할 필요없이이 패턴을 설계하는 방법은 무엇입니까? 또는이 시나리오를 처리하는 가장 우아한 방법은 무엇입니까?

+8

... 왜 이렇게하고 싶습니까? 이 서비스는 어떤 용도로 사용됩니까? 불필요한 상속처럼 보이는 것을 부과하지 않고 여분의 동작을 처리하기 위해 함수 인터페이스에서'default' 함수를 정의하지 않는 것이 어떻습니까? – Makoto

+6

캐스트가 없다면, 컴파일러가'Second'의 람다 구현을 원한다고 추론 할 방법이 없습니다. 캐스팅은 컴파일러에게 가장 좋고/가장 쉬운 방법이므로, 캐스팅 *은이 시나리오를 처리하는 가장 우아한 방법입니다. – Andreas

+2

@Makoto 좋은 점은 First는 라이브러리에서 변경 될 수는 없지만 확장 된 것이라고 가정합니다. – AndresQ

답변

0

그것은 또한 인수로 Second의 인스턴스를 받아 있도록, methodThatTakeFirst 과부하 수 있고, 대표는methodThatTakeFirst(First first)에 :

void methodThatTakeFirst(First first) { 
    // play with first 
} 

void methodThatTakeFirst(Second second) { 
    methodThatTakeFirst((First) second); // casting necessary 
} 

캐스트, 그 컴파일러 실제로 대의원 그래서 methodThatTakeFirst(First first)에 중요하다 그렇지 않으면 StackOverflowError이됩니다.

이 디자인이 좋은지 아닌지는 잘 모르겠지만이 질문의 범위를 벗어난 것 같습니다.

0

어쩌면 다른 람다를 추가할까요?

void secondMethod(Second second) { 
     methodThatTakeFirst(x-> second.fun(x,x)); 
    }