노션으로 다시 돌아갔습니다 😅

익명 클래스...? 익명 객체...?

by mignon25

람다식이 결국 익명객체라고 하는데 익명객체가 뭔지 모르겠다. 

그래서 익명 객체에 대해서 먼저 정리해보았다. 

 

익명 객체(익명 클래스)란?

이름이 없는 객체. 
프로그램에서 일시적으로 한번만 사용되고 버려지는 객체.

 

 

익명 클래스를 사용해야 하는 상황?

  1. 프로그램 내에서 일시적으로(단발성으로) 한 번만 사용되어야 하는 객체일 경우
    • UI 이벤트 처리, 스레드 객체 등 (단발성 이벤트 처리)
  2. 재사용성이 없고, 확장성을 활용하는 것이 오히려 유지보수에서 더 불리할 때.
    • 비즈니스 로직이 정말 제각각이며, 재사용성이 전혀 없어 매번 클래스를 생성해야 하는 비용이 더 클 때

 

 

익명 객체 구현하기 (1) -  익명 자식 객체 생성

부모 / 자식 간 상속 아래 익명 자식 객체 생성

 

익명 자식객체를 생성은 3가지 방법으로 구현할 수 있다.

  1. 필드의 초기값
  2. 로컬변수의 초기값
  3. 매개변수의 매개값
// 곤충이라는 부모 클래스 가정
class Insect { 
    void attack() {
        System.out.println("곤충은 공격을 한다.");
    }
}

public class Anonymous {

    // 👉🏻방법 1 : 필드에 익명 자식 객체 생성
    Insect spider1 = new Insect() {

        String name = "무당거미";

        // 거미줄을 치다.
        void cobweb() {
            System.out.println(name + " : 사각형으로 거미줄을 친다.");
        }

        @Override
        void attack() {
            System.out.println(name + " : 독을 발사한다. ");
        }
    };

    // 👉🏻 방법 2 : 로컬변수의 초기값으로 대입
    void method1() {
        Insect spider2 = new Insect() {

            String name = "늑대거미";

            // 거미줄을 치다
            void cobweb() {
                System.out.println(name + " : 육각형으로 거미줄을 친다.");
            }

            @Override
            void attack() {
                System.out.println(name + " : 앞니로 문다. ");
            }
        };

        // 로컬변수이기 때문에 메서드에서 바로 사용
        spider2.attack();
    }


    // 👉🏻방법 3 : 익명객체 매개변수로 대입
    void method2(Insect spider) {
        spider.attack();
    }
    
    
    // 실행 메서드
    public static void main(String[] args) {

	Anonymous a = new Anonymous();

    // 방법 1 : 익명객체 필드 사용
    a.spider1.attack();

    // 방법 2 : 익명객체 로컬변수 사용
    a.method1();

    // 방법 3 : 매개변수로 익명객체 사용
    a.method2(new Insect() {
       String name = "타란튤라";

       // 거미줄을 친다.
        void cobweb() {
            System.out.println(name + " : 그냥 마구잡이로 친다");
        }

        @Override
        void attack() {
            System.out.println(name + " : 공격 안하고 후퇴한다. ");
        }
    });

    // 익명객체 내부에서 새롭게 정의된 필드, 메서드는 부모객체 타임의 참조변수로 접근 불가
    a.spider1.name = "왕거미"; // 접근 불가 (익명객체에서 새롭게 정의한 필드)
    a.spider1.cobweb(); // 접근 불가 (익명객체에서 새롭게 정의한 메서드)
    a.spider1.attack(); // 접근 가능 (부모클래스 Insect 의 메서드 오버라이딩한 것) 
    
    }

}

 

 

익명 객체 구현하기 (2) - 익명 구현 객체

함수형 인터페이스를 구현한 객체 -> 람다식으로 표현할 수 있다. 

 

익명 객체는 이벤트 UI에 많이 활용된다고 한다.

public class Button {
    // 인터페이스 타입 필드
    OnClickListener onClickListener;

    // 중첩 인터페이스. => 버튼이 클릭되었을 때의 동작을 정의하는 메서드를 가지고 있다.
    interface OnClickListener {
        void onClick();
    }

    // 구현 객체의 onClick() 메서드 호출
    void touch() {
        onClickListener.onClick();
    }

    public OnClickListener getOnClickListener() {
        return onClickListener;
    }

    // 필드멤버변수 onClickListener 에 대한 Setter
    // 외부에서 해당 Setter 로 값을 지정하기 위해서는 매개변수로 내부 인터페이스 타입을 구현한 객체를 전달해야 한다.
    // 그 내부 인터페이스는 추상메서드를 하나만 가지는 함수형 인터페이스이므로 => 람다식을 넣어서 전달할 수도 있다.
    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }
}

class Test {
    public static void main(String[] args) {
        Button button = new Button();

        // onClick() 의 동작 Setter 로 지정
        button.setOnClickListener(() -> System.out.println("버튼 클릭!!!!"));

        // 지정한 동작을 실행
        button.touch();   // 버튼 클릭!!!!

        Button startBtn = new Button();
        Button endBtn = new Button();

        // startBtn 과 endBtn 에 각각 다른 동작 지정
        startBtn.setOnClickListener(() -> System.out.println("프로그램을 시작합니다!!"));
        endBtn.setOnClickListener(() -> System.out.println("프로그램을 종료합니다!!"));

        startBtn.touch();  // 프로그램을 시작합니다!!
        endBtn.touch();   // 프로그램을 종료합니다!!

    }
}

// 출력 결과
버튼 클릭!!!!
프로그램을 시작합니다!!
프로그램을 종료합니다!!

 

 

 

 

블로그의 정보

Mignon'S Dev Log

mignon25

활동하기