익명클래스(inner클래스 중 하나)
- 객체의 선언과 생성을 동시에 하여 오직 하나의 객체를 생성하고, 단 한 번만 사용되는 일회용 클래스
- 익명 객체 : 자기 자신을 만드는 클래스의 이름이 없는 객체(클래스 없이 만들어지는 객체) → 1회용 객체(클래스는 여러개의 객체)
- 익명 자식 객체, 익명 구현 객체(인터페이스를 구현해서 만드는 객체, 인터페이스 타입의 참조변수에 할당할 수 있다.)
1. 기존에 정의된 클래스를 활용하여 이름없이 객체 생성 시 오버라이딩하여 사용
- 객체를 상속해서 다른 클래스로 정의한게 아니고, 그때그때 새로운 익명클래스 객체를 만들어 반환함
public class _01_AnonymousClass1 {
public static void main(String[] args) {
Coffee specialCoffee = new Coffee() {
@Override
public void order(String coffee) {
super.order(coffee);
System.out.println("(귓속말) 딸기 케이크는 서비스예요.");
}
@Override
public void returnTray() {
System.out.println("(귓속말) 자리에 두시면 제가 치울게요.");
}
};
specialCoffee.order("바닐라 라떼");
specialCoffee.returnTray();
}
}
class Coffee {
public void order(String coffee) {
System.out.println("주문하신 " + coffee + " 나왔습니다.");
}
public void returnTray() {
System.out.println("커피 반납이 완료되었습니다.");
}
}
2. 추상클래스를 직접 구현하면서 해당 객체를 바로 전달(return)함
public class _02_AnonymousClass2 {
public static void main(String[] args) {
HomeMadeBurger momMadeBurger = getMomMadeBurger();
momMadeBurger.cook();
System.out.println("----------------------------");
}
public static HomeMadeBurger getMomMadeBurger() {
return new HomeMadeBurger() {
@Override
public void cook() {
System.out.println("집에서 만드는 엄마표 수제 버거");
System.out.println("재료 : 빵, 소고기패티, 해시브라운, 양상추, 마요네즈, 피클");
}
};
}
}
abstract class HomeMadeBurger {
public abstract void cook();
}
3. 함수형인터페이스 사용(익명 구현 객체) @FunctionalInterface
- 단 하나의 추상 메서드만 선언(람다식과 인터페이스의 메서드가 1:1로 매칭)
- 메서드를 클래스 내에서 선언하는게 아닌, 클래스 밖에서 선언하여 사용함 (자바는 객체지향이라 무조건 클래스 내에 위치해야 하는데, 함수형인터페이스를 통해 익명 구현 객체의 메서드로 우회해서 처리하는 것임)
public class LamdaExample1 {
public static void main(String[] args) {
Object obj = new Object() { //람다식을 객체로 표현 // 람다식 Object obj = (num1, num2) -> num1 + num2; 로 대체 가능
int sum(int num1, int num2) { return num1 + num1;}
};
obj.sum(1, 2); //Error
//Object 클래스에는 sum이라는 메서드가 없으므로,
//Object 타입의 참조변수에 담는다고 하더라도 sum 메서드를 사용할 수 없음
//-> 함수형 인터페이스 필요
//함수형인터페이스를 사용하여 내부 메서드를 사용하게끔 함
MyFunctionalInterface example = (x) -> System.out.println(x * 5);
example.accept(2);
}
}
@FunctionalInterface
interface MyFunctionalInterface {
void accept(int x);
}
람다식(=익명함수) JDK 1.8이후 사용가능
- 익명클래스를 함수식으로 표현하는 방식으로 간결한 형태의 코드 뭉치 : 1회성, 리스트에서 많이 사용됨
- 메서드를 하나의 식으로 표현 → 변수에 할당할 수 있다.
- 함수형인터페이스만 람다식의 타입으로 사용될 수 있음
반환타입 제거, 메서드명 없음, 중괄호 생략가능(1줄일경우)
(전달값1, 전달값2, …) →{ 코드 }
pubic void print(String s){
System.out.println(s);
}
s -> System.out.println(s)
//접근제어자, 반환타입, 메서드명 생략, 전달값 타입 생략
//한줄이면 중괄호(세미콜론) 생략
public int add(int x, int y){
return x+y;
}
(x,y)-> {return x+y} //전달값2개 이상이면 소괄소 생략 불가, 반환값 이으면 중괄호 생략 불가
(x,y)-> x+y //리턴 생략해도 결과 반환해줌
<함수형 인터페이스와 람다 사용예제>
public class LamdoCalculator {
public static void main(String[] args) {
Calculable add = (a,b) -> a + b; //함수형 인터페이스 내 메서드 정의
Calculable sub = (a,b) -> a - b;
add.calculate(1,2);
operate(add, 10,2); // add를 정의해서 operate 호출(add가 재사용가능함)
operate((a,b) -> a+b, 2,3); // 이게 최종 형상 (1회성으로 사용할 때 유리)
}
//람다식과 값 두개를 받아와서 람다식에 해당하는 연산을 수행 후 출력
private static void operate(Calculable cal, int a, int b){
System.out.println(cal.calculate(a,b));
}
}
@FunctionalInterface
interface Calculable{
int calculate(int a, int b);
}
'Coding > 언어-JAVA' 카테고리의 다른 글
JAVA 사용자 입출력(Scanner, Printf) (0) | 2023.08.17 |
---|---|
JAVA 스트림(Stream) #Day8 (0) | 2023.08.16 |
JAVA 에너테이션 #Day7 (0) | 2023.08.12 |
JAVA 열거형(Enum) #Day7 (0) | 2023.08.11 |
JAVA 예외(try-catch) #Day7 (0) | 2023.08.11 |