728x90
반응형
익명클래스
java에서는 아래와 같은 클래스가 있을 때, 익명 클래스로 만들 수 있다.
// 부모 클래스
class Animal {
public String bark() {
return "동물이 웁니다";
}
}
// 자식 클래스
class Dog extends Animal {
@Override
public String bark() {
return "개가 짖습니다";
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog();
a.bark();
}
}
class Animal {
public String bark() {
return "동물이 웁니다";
}
}
public class Main {
// 익명 클래스 : 클래스 정의와 객체화를 동시에. 일회성으로 사용
public static void main(String[] args) {
Animal a = new Animal() {
@Override
public String bark() {
return "개가 짖습니다";
}
}; // 단 익명 클래스는 끝에 세미콜론을 반드시 붙여 주어야 한다.
a.bark();
}
}
익명클래스의 장점과 한계점
익명 클래스는 재사용할 필요가 없는 일회성 클래스를 따로 클래스를 정의할 필요 없이 간단하게 만들 수 있게 해준다. 코드가 줄 뿐만 아니라, 메모리 면에서도 효율적이다.
이러한 익명 클래스는 UI 이벤트처리, 스레드 객체 ..등 단발성 이벤트 처리에 자주 애용된다.
익명 클래스는 전혀 새로운 클래스를 익명으로 사용하는 것이 아니라, 이미 정의되어 있는 클래스의 멤버들을 재정의 하여 사용할 필요가 있을때 그리고 그것이 일회성으로 이용될때 사용하는 기법이다.
즉, 익명 클래스는 부모 클래스의 자원을 일회성으로 재정의하여 사용하기 위한 용도 인 것이다.
다만, 익명클래스는 하나의 인터페이스를 상속 받을 때에만 사용이 가능하므로, 여러개의 인터페이스를 상속받았다면, 이전과 같이 클래스를 만들어주어야 한다.
익명 객체와 람다
람다를 사용하여 익명 클래스의 코드를 더 줄이고, 가독성을 높일 수 있다.
먼저 익명 클래스를 사용한 예시를 보자.
// 연산식을 추상화한 인터페이스
interface Operate {
int operate(int a, int b);
}
// 계산을 담당하는 클래스
class Calculator {
// 계산할 두 수를 저장하는 필드
private final int a;
private final int b;
// 생성자
public Calculator(int a, int b) {
this.a = a;
this.b = b;
}
// 인터페이스 타입을 매개변수로 받는 메소드 (다형성)
public int caculate(Operate op) {
return op.operate(this.a, this.b); // 매개변수 객체의 메서드 실행하여 리턴
}
}
public class Main {
public static void main(String[] args) {
// 계산할 두 수
int num1 = 20;
int num2 = 10;
// Calculator 클래스 생성하며 계산 할 수를 클래스 필드에 저장
Calculator calculator = new Calculator(num1, num2);
// calculator.caculate() 메서드 인자로, operate() 추상 메소드를 더하기 연산이 되도록 재정의한 익명 구현 객체를 넘김
// calculator.caculate() 매서드 내에서 재정의된 operate() 메소드가 실행되어 a + b가 리턴 됨
int result = calculator.caculate(new Operate() {
public int operate(int a, int b) {
return a + b;
}
});
System.out.println(result); // 30
// calculator.caculate() 메서드 인자로, operate() 추상 메소드를 빼기 연산이 되도록 재정의한 익명 구현 객체를 넘김
// calculator.caculate() 매서드 내에서 재정의된 operate() 메소드가 실행되어 a - b가 리턴 됨
int result2 = calculator.caculate(new Operate() {
public int operate(int a, int b) {
return a - b;
}
});
System.out.println(result2); // 10
}
}
이걸 람다로 줄이면 아래와 같다.
Operate operate = new Operate() {
public int operate(int a, int b) {
return a + b;
}
};
// 람다식으로 줄이기
Operate operate = (a, b) -> {
return a + b;
};
// 더 짧게 줄이기 (리턴 코드만 있다면 생략이 가능)
Operate operate = (a, b) -> a + b;
public class Main {
public static void main(String[] args) {
// 계산할 두 수
int num1 = 20;
int num2 = 10;
// Calculator 클래스 생성하며 계산 할 수를 클래스 필드에 저장
Calculator calculator = new Calculator(num1, num2);
// operate() 추상 메소드를 더하기 연산이 되도록 재정의한 익명 구현 객체
Operate operate = (a, b) -> a + b;
// calculator.caculate() 매서드에 람다식을 넣음
int result = calculator.caculate(operate);
System.out.println(result); // 30
// 아니면 람다식 자체를 메소드 인자로 바로 넘겨줄 수 도 있다.
int result2 = calculator.caculate((a, b) -> {
return a - b;
});
System.out.println(result2); // 10
}
}
참고
728x90
반응형
'java' 카테고리의 다른 글
[java] Variable used in lambda expression should be final or effectively final, 람다 캡처링 (0) | 2023.12.08 |
---|---|
[java] lambda를 이용해 callback 구현하기 (0) | 2023.07.28 |
[java] 코드 실행시간 측정하기 (0) | 2023.03.31 |
[java] List, Map에서 유용하지만 생소한 함수 정리 (0) | 2023.03.24 |
[java] Spring JDBC에서 배치처리하기 (0) | 2023.01.17 |