JAVA

[Java] 익명 클래스

songsua 2025. 2. 16. 15:34

익명 클래스는 지역클래스의 특별한 종류의 하나이다.

익명 클래스는 지역 클래스인데 이름이 없다는 특징이 있다.

 

익명 클래스(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