익명 클래스는 지역클래스의 특별한 종류의 하나이다.
익명 클래스는 지역 클래스인데 이름이 없다는 특징이 있다.
익명 클래스(Anonymous Class)란?
익명 클래스는 이름이 없는 클래스로, 보통 특정 인터페이스나 클래스를 즉석에서 구현할 때 사용
주로 일회성 사용을 위한 목적으로 사용되며, 코드의 간결성을 높일 수 있다.
new Printer() {Body}
익명 클래스는 클래스의 본문(body)을 정의하면서 동시에 생성한다.
new 다음에 바로 상속 받으면서 구현할 부모타입을 입력하면 된다.
이 코드는 인터페이스를 생성하는 것이 아니고 Printer 라는 이름의 인터페이스를 구현한 익명 클래스를 생성하는 것이다.
예시
// 1. 인터페이스 정의
interface Animal {
void sound();
}
// 2. 클래스를 만들어서 구현
class Dog implements Animal {
@Override
public void sound() {
System.out.println("멍멍!");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog(); // 객체 생성
dog.sound(); // 출력: 멍멍!
}
}
이런식으로 할 경우에는 인터페이스만드는 것이 귀찮다.
익명클래스로 간단하게 만들어보기
public class Main {
public static void main(String[] args) {
// 익명 클래스를 이용해 인터페이스 구현
Animal dog = new Animal() {
@Override
public void sound() {
System.out.println("멍멍! (익명 클래스)");
}
};
dog.sound(); // 출력: 멍멍! (익명 클래스)
}
}
- new Animal() { ... } : 클래스를 만들면서 동시에 객체를 생성.
- 이름이 없는 클래스를 만들어서, sound() 메서드를 오버라이딩한 것.
- 기존보다 코드가 짧고 간단
익명클래스 활용
package anonymous.ex;
public class Ex0Main {
public static void helloJava() {
System.out.println("프로그램 시작");
System.out.println("핼로 자바");
System.out.println("program end");
}
public static void helloSpring() {
System.out.println("프로그램 시작");
System.out.println("핼로 spring");
System.out.println("program end");
}
//메서드에 중복이 보이기 때문에 하나로 합칠려고 한다.
public static void main(String[] args) {
}
}
위에 보면 메서드에 중복이 보이기 때문에 중복을 제거해서 메서드를 한 개로 통합할려고 한다.
변하지 않는 부분은 "프로그램 시작" , "program end" 이 있는 걸 알 수 있다.
그러면 void 메서드이름(str name) {..} 을 두고 메서드를 생성하면, 메서드 하나로 간결하게 만들 수 있다.
활용2
package anonymous.ex;
import java.util.Random;
public class Ex1Main {
public static void helloDice() {
System.out.println("프로그램 시작");
//코드 조각 시작
int randomValue = new Random().nextInt(6) + 1;
System.out.println(randomValue);
//코드 조각 종료
System.out.println("프로그램 종료");
}
public static void helloSum() {
System.out.println("프로그램 시작");
//코드 조각 시작
for (int i = 0; i < 3; i++) {
System.out.println("i + " + i);}
//코드 조각 종료
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
helloDice();
helloSum();
}
}
해당 코드도 하나의 메서드에서 실행할 수 있도록 리팩토링해보자.
이번에는 문자열 같은 데이터가 아니라 코드 조각을 전달해야하는 것을 생각해야 한다.
package anonymous.ex;
import java.util.Random;
public class Ex1Main2 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
//코드 조각 종료
System.out.println("프로그램 종료");
}
//인터페이스 가져와서 dice, sum class 만들기
static class Dice implements Process {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println(randomValue);
}
static class sum implements Process {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("i = " + i);
}
}
}
public static void main(String[] args) {
hello(new Dice()); //Dice클래스의 메서드 실행
hello(new sum()); // sum 클래스의 메서드 실행
}
}
}
어떻게 외부에서 코드 조각을 전달할 수 있을까?
코드 조각 보통 메서드(함수)에 정의한다. 따라서 코드 조각을 전달하기 위해서는 메서드가 필요하다.
그런데 지금까지 학습한 내용으로는 메서드를 전달할 수 있는 방법이 없는데, 대신에 인스턴스를 전달하고, 인스턴스에 있는 메서드를 호출하면 된다.
그래서 이 문제를 해결하기 위해 인터페이스를 정의하고 구현 클래스를 만든 것이다.
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
Process 인스턴스 만들고 그 안에 있는 process.run 메서드를 호출했다.
코드 조각을 메서드에 전달할 때는 인스턴스를 전달하고 해당 인스턴스에 있는 메서드를 호출하면 된다.
활용3
지역클래스를 사용해서 같은 기능을 구현해보자
만든 두 메서드는 Main에서만 생성해서 사용되고 있다.
package anonymous.ex;
import java.util.Random;
public class Ex1Main3 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
//코드 조각 종료
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
//인터페이스 가져와서 dice, sum class 만들기
class Dice implements Process {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println(randomValue);
}
}
class Sum implements Process {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("i = " + i);
}
}
}
Dice dice = new Dice();
Sum sum = new Sum();
hello(dice);
hello(sum);
}
}
이렇게 Main 에서 실행하도록 설정할 수 있다. 여기서 익명클래스 사용해보자
package anonymous.ex;
import java.util.Random;
public class Ex1Main3 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
//코드 조각 종료
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
//인터페이스 가져와서 dice, sum class 만들기
Process dicd = new Process() {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println(randomValue);
}
};
Process sum = new Process() {
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("i = " + i);
}
}
};
hello(dicd);
hello(sum);
}
}
이보다 더 간단하게 코드 조각만을 전달하기 위해서 자바8부터 "람다" 을 사용하게 되었다.
hello(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
});
'JAVA' 카테고리의 다른 글
[Java] 예외 처리 (0) | 2025.02.16 |
---|---|
[Java] 지역 클래스 (0) | 2025.02.15 |
[Java] Thread (2) | 2025.02.11 |
[Java] 제네릭 (0) | 2025.02.09 |
[Java] 중첩 클래스, 내부 클래스 (0) | 2025.02.09 |