Language/Java

[JAVA] 익명 클래스

leegeonwoo 2024. 6. 9. 17:29

anonymous class - 지역 클래스이지만 이름이 없다는 의미를 가지고있다

보통의 클래스나 지역 클래스를 사용하기 위해서는

  • 클래스를 선언
  • 클래스를 new로 생성
    위와 같이 두 가지의 과정을 거쳤다.

===익명 클래스를 사용하면 클래스의 이름을 생략하고, 클래스의 선언과 생성을 한번에 처리할 수 있다===

익명 클래스 사용 전

public class AnonymousOuter {  

    private int outInstatnceVar = 3;  

    public void process(int paramVar) {  
        int localVar = 1;  

        class LocalPrinter implements Printer{  
            int value = 0;  

            @Override  
            public void print() {  
                System.out.println("value = " + value);  
                System.out.println("localVar = " + localVar);  
                System.out.println("paramVar = " + paramVar);  
                System.out.println("outInstatnceVar = " + outInstatnceVar);  
            }  
        }  

        LocalPrinter printer = new LocalPrinter();  


        printer.print();  
    }  

    public static void main(String[] args) {  
        AnonymousOuter outer = new AnonymousOuter();  
        outer.process(2);  
    }  
}

익명 클래스 사용 후

public class AnonymousOuter {  

    private int outInstatnceVar = 3;  

    public void process(int paramVar) {  
        int localVar = 1;  

        Printer printer = new Printer() {  
            int value = 0;  

            @Override  
            public void print() {  
                System.out.println("value = " + value);  
                System.out.println("localVar = " + localVar);  
                System.out.println("paramVar = " + paramVar);  
                System.out.println("outInstatnceVar = " + outInstatnceVar);  
            }  
        };  

        printer.print();  
    }  

    public static void main(String[] args) {  
        AnonymousOuter outer = new AnonymousOuter();  
        outer.process(2);  
    }  
}

Printer는 인터페이스이기때문에 객체로 생성할 수 없다.
익명 클래스에서는 Printer printer = new Printer(){ body }와 같이 사용할 수 있는데
Printer의 인스턴스를 생성하는 것이아니고 Printer라는 인터페이스를 구현한 익명 클래스를 생성하는 것이다. {body} 부분에 구현하고자하는 코드를 작성하면 된다.

익명 클래스의 특징

  • 익명 클래스는 이름 없는 ===지역클래스를 선언하면서 동시에 생성한다===
  • 익명 클래스는 반드시 부모 클래스를 상속 받거나 인터페이스를 구현해야 한다 즉, ===익명 클래스를 사용하려면 상위 클래스나 인터페이스가 필요하다===
  • 생성자를 가질 수 없기때문에 기본생성자만 사용된다

익명 클래스의 장점

  • 클래스를 별도로 정의하지 않고도 인터페이스나 추상클래스를 즉석에서 구현할 수 있어서 코득 ㅏ더 간결해진다
  • (재사용이 필요한 클래스는 별도로 정의해주는 것이 좋음)

지역 클래스의 사용

public class Ex2RefMain {  

    public static void run(Game game) {  
        System.out.println("프로그램 시작");  
        game.play();  
        System.out.println("프로그램 종료");  
    }  



    public static void main(String[] args) {  

        class Dice implements Game{  

            @Override  
            public void play() {  
                int randomValue = new Random().nextInt(6) + 1;  
                System.out.println("randomValue = " + randomValue);  
            }  
        }  

        class Sum implements Game{  

            @Override  
            public void play() {  
                for (int i = 0; i < 3; i++) {  
                    System.out.println("i = " + i);  
                }  
            }  
        }  
        run(new Dice());  
        run(new Sum());  
    }  
}

다형성을 구현한 run메서드를 실행하기위해서 반드시 new키워드를 통해 인스턴스를 생성하고 해당하는 인스턴스의 play메서드가 main메서드에서 호출되게한다.

===여기서 알 수 있는것은 메서드를 호출하기위해서는 반드시 메서드를 매개변수로 전달해준다는 점이고 메서드를 전달하기위해서는 인스턴스를 생성해주어야만한다.===

인스턴스를 생성하지않고 메서드만을 전달할수는 없을까? 라는 생각에서 사용하는 것이 익명 클래스이다.

익명 클래스 사용

public class Ex4RefMain {  

    public static void run(Game game) {  
        System.out.println("프로그램 시작");  
        game.play();  
        System.out.println("프로그램 종료");  
    }  



    public static void main(String[] args) {  
        run(new Game() {  
            @Override  
            public void play(){  
                int randomValue = new Random().nextInt(6) + 1;  
                System.out.println("randomValue = " + randomValue);  
            }  
        });  

        run(new Game() {  
            @Override  
            public void play() {  
                for (int i = 0; i < 3; i++) {  
                    System.out.println("i = " + i);  
                }  
            }  
        });  
    }  
}

익명클래스를 사용함으로써 인스턴스를 따로 변수로받아 넘기지않고 메서드 코드를 바로 넘기듯이 코드를 작성할 수 있게되었다.

[!NOTE] 익명클래스 -> 람다
이 익명 클래스는 후에 자바8에서 람다가 등장하는데에 기반이 되었으며 코드는 아래와 같다
람다에 대해서는 후에 자세히 배운다

public class Ex5RefMain {  

    public static void run(Game game) {  
        System.out.println("프로그램 시작");  
        game.play();  
        System.out.println("프로그램 종료");  
    }  



    public static void main(String[] args) {  
        run(() -> {  
            int randomValue = new Random().nextInt(6) + 1;  
            System.out.println("randomValue = " + randomValue);  
        });  

        run(() -> {  
            for (int i = 0; i < 3; i++) {  
                System.out.println("i = " + i);  
            }  
        });  
    }  
}

공부자료 참조: 인프런 - 김영한
https://www.inflearn.com/users/74366/@yh

728x90