1. 람다 식
(1) 정의
익명 함수(이름이 없는 함수) == 액세스 한정자, 반환 유형, 함수 이름 및 매개변수 데이터 유형은 모두 불필요합니다.
람다 식도 일급 객체입니다.
**프라임 속성이란 무엇입니까?
데이터나 변수를 받을 수 있는 객체, 특정 메서드의 매개변수로 입력할 수 있는 객체, 특정 메서드의 반환값이 될 수 있는 객체입니다.
(2) 모양
(패스 값 1, 패스 값 2, …) -> { 코드 }
2. 기능적 인터페이스
(1) 의미
하나의 추상 메서드만 있는 인터페이스
(2) 람다 식과의 관계
람다 식은 기능적 인터페이스를 통해서만 액세스할 수 있습니다.
**왜?
인터페이스에 두 개의 추상 메서드가 있는 경우 어떤 추상 메서드가 람다 식과 일치하는지 모호해집니다.
따라서 하나의 추상 메서드만 있는 기능적 인터페이스만 람다 식과 일치시켜 사용할 수 있습니다.
(둘 사이의 매개변수 개수와 반환값 유무가 일치해야 합니다.
)
3. 코드 리뷰
(1) 인수가 하나이고 반환형이 void인 추상 메서드의 경우
// <<인터페이스 부분>>
//함수형 인터페이스에 추상 매소드가 1 개여야만 한다고 컴퓨터에게 가르쳐 주기 위해 어노테이션 이용
// 해당 어노테이션 있으면, 추상 매소드가 2개가 될 때, 컴퓨터가 에러를 말해준다.
@FunctionalInterface
public interface Convertible {
// USD를 환전하는 추상 매소드
void convert(int USD);
}
/* 함수형 인터페이스 객체와 그 객체의 매소드에 넣을 값으로 이루어진 함수
인터페이스는 일반적으로 객체를 가질 수 없지만, 람다식으로 추상매소드를 바로 구체화 시키기 때문에
람다식으로 매칭한 경우에는 가능 */
public static void convertUSD(Convertible converter, int USD){
converter.convert(USD);
}
}
// 람다식을 통해 인터페이스에서 바로 객체를 생성했고,
//(다형성의 원리: 부모 클래스의 참조 변수는 자식 클래스의 객체를 참조할 수 있다.
)
Convertible convertible = (USD) -> System.out.println(USD + "달러 = "+ (USD *1400) + " 원");
// 만들어진 객체와 해당 객체 매소드에 넣을 값을 파라미터로 보냈다.
// 람다식이 곧 추상 매소드의 구체화 이므로 해당 2는 USD로 보내진다.
convertUSD(convertible,2);
// * 객체 생성 과정 없이 람다식 자체를 파라미터로 보낼 수도 있다.
// * 어짜피 파라미터인 Convertible converter와 만나 객체가 생성되므로 밑과 같은 표기도 가능하다.
convertUSD((USD) -> System.out.println(USD + "달러 = "+ (USD *1400) + " 원"), 1);
(2) 추상 메서드에 인수가 없고 반환 유형이 유효하지 않은 경우
// 함수형 인터페이스
@FunctionalInterface
public interface ConvertibleWithNoParams {
void convert();
}
ConvertibleWithNoParams c1 = () -> System.out.println("1달러는 1400원");
// 추상 매소드 호출하면 위의 람다식이 해당 호출에 응하여 일을 수행한다.
c1.convert();
(3) 람다 식의 코드 부분이 한 줄인지 두 줄 이상인지 구분
** 람다 식의 코드 부분이 두 줄 이상인 경우 () -> {}; 까지 {}; 부분을 작성해야 합니다.
(한 줄이면 생략 가능)
// 위의 함수형 인터페이스 계속 사용
c1 = () -> {
int USD = 5;
int KRW = 1400;
System.out.println(USD + "달러 = "+ (USD *KRW) + " 원");
};
(3) 추상 메서드에 두 개 이상의 인수가 있는 경우 반환 형식은 무효입니다.
** 둘 사이의 인수 수를 일치시킬 수 있습니다.
public interface ConvertibleWithTwoParams {
void convert(int USD, int KRW);
}
ConvertibleWithTwoParams c2 = (USD, KRW) -> System.out.println(USD + "달러 = "+ (USD *KRW) + " 원");
c2.convert(10,1400);
(4) 추상 메서드에 반환 값이 있는 경우
** 반환 {}가 있어도; 작성합니다.
** 추상 메서드에 반환 유형이 있다고 해서 반드시 반환되어야 하는 것은 아닙니다.
= ~~; 람다 식으로 작성합니다.
다음과 같이 리턴을 제거하면 최소한 람다 식은 리턴 옆에 배치합니다.
// int 반환값이 필요한 인터페이스
@FunctionalInterface
public interface ConvertibleWithReturn {
int convert(int USD, int KRW);
}
//원래 return을 써서 나타내면 {return USD*KRW;}; 로 해야하지만, return을 안 쓰니 {};을 쓸 의무도 사라졌다.
ConvertibleWithReturn c3 = (USD, KRW) -> USD * KRW;
int result = c3.convert(20, 1400);
System.out.println("20 달러 = "+result+" 원");
4. 직접 해보기
/* 추상 매소드 인수 1개, 반환형 void 인 경우(함수 경유 나타내기, 그냥 나타내기)
* 추상 매소드가 인수도 없고 반환형도 void 인 경우
* 추상 매소드가 인수 2개에 반환형도 있는 경우 */
import WorkOut_Myself.Translator.TranslateEngTo;
import WorkOut_Myself.Translator.TranslateHitoKR;
import WorkOut_Myself.Translator.TranslateTwo;
public class FunctionalInterface_myself {
public static void main(String() args) {
TranslateEngTo Hello = (hello) -> System.out.println(hello +"은(는) 한국어로 \"안녕하세요\" 입니다.
");
EngToKR(Hello,"Hi");
EngToKR((Hi) -> System.out.println(Hi +"은(는) 한국어로 \"안녕하세요\" 입니다.
"),"하지메마시테" );
TranslateHitoKR AnyLanguage = () -> System.out.println("Hello는 한국어로 \"안녕하세요.\" 입니다.
");
AnyLanguage.Translate();
TranslateTwo Korean = (ENG, JPN) -> {
return "영어인 " + ENG + "은(는) 한국어로 안녕하세요 입니다.
그리고 일본어인 " + JPN + "은(는) 한국어로 안녕하세요 입니다.
";
};
String s = Korean.Translate("Hello!
", "곤니치와");
System.out.println(s);
}
public static void EngToKR (TranslateEngTo TL, String s){
TL.Translate(s);
}
}