ch09. 중첩 클래스와 중첩 인터페이스

728x90

ch09. 중첩 클래스와 중첩 인터페이스

09-1. 중첩 클래스와 중첩 인터페이스

➡️인스턴스 멤버 : 객체 생성없이 사용 불가능한 멤버 ( 객체마다 소속되는 멤버)

➡️정적 멤버 : 객체 생성없이도 사용 가능한 멤버 ( 클래스에 고정된 멤버) , 클래스로 바로 접근해서 사용 O

[중첩 클래스] : Nested 네스티드 클래스

중첩 클래스 : 클래스 내부에 선언한 클래스

→ 클래스 내부에 에 따라

→ 선언된 위치에 따라

<멤버 클래스> : 바깥 클래스 블록 내부에 클래스의 멤버로서 선언된 중첩 클래스

: 바이트 코드 이름 : 바깥 $ 멤버.class

✅인스턴스 멤버 클래스

: 바깥 객체가 생성되어야만 생성해서 사용 가능한 멤버 클래스

: (static) 키워드 없이 선언된 멤버 클래스

: 클래스 내부에 인스턴스 필드와 메소드만 선언 가능

  **<<객체 생성 방법>>**

바깥 클래스 외부에서 객체 생성 시, 바깥 객체 생성 후 -> 안쪽 객체 생성 가능

바깥 클래스 내부에서 객체 생성 시, 자기 객체 생성해서 사용

✅정적 멤버 클래스

: 바깥 객체 생성 없이도 클래스로 바로 접근해서 객체 생성 가능한 멤버 클래스

: (static) 키워드로 선언된 멤버 클래스

: 클래스 내부에 모든 종류의 필드,메소드 선언 가능

<<객체 생성 방법>>

바깥 클래스 외부에서 객체 생성 시, 바깥 객체 생성없이 바로 클래스로 접근해서 자기 객체 생성 O

✅로컬 클래스

[중첩 클래스의 접근 제한]

<바깥 클래스 필드.메소드에서// 멤버 클래스 객체 생성에 대한 제한>

바깥 인스턴스 필드, 메소드 ( 바깥 객체 생성해야만 사용 가능한 멤버)

→ 인스턴스 멤버 클래스의 객체 생성 O 사용 O

→ 정적 멤버 클래스의 객체 생성 O 사용 O

바깥 정적 필드, 메소드 (바깥 객체 생성 없이도 사용 가능한 멤버)

→ 정적 멤버 클래스의 객체 생성 O 사용 O

: 인스턴스 멤버 클래스는 바깥 객체 생성되어야만 사용 가능한 멤버 클래스이므로

객체 생성 없이도 사용 가능한 static 타입 멤버로는 객체 생성 불가능

<멤버 클래스 내부에서// 바깥 클래스 멤버에 접근 제한>

인스턴스 멤버 클래스 안에서 -> 바깥 클래스의 모든 필드.메소드 접근 O

정적 멤버 클래스 안에서 -> 바깥 클래스의 정적 필드.메소드에만 접근 O

: A 객체 생성 후 B 객체 생성되고, B 객체 생성되어야 B객체 내부 메소드 호출됨

: B 객체 내부에서는 A,B 객체의 멤버 모두 사용 O

: A 객체 생성 없이도 생성 가능한 C 객체는,

 A 객체 생성되어야만 사용가능한 A의 인스턴스 멤버를 C객체 내부에서 사용 X

 A 객체 생성 없이도 사용 가능한 A의 정적 멤버는 C 객체 내부에서 사용 O

<로컬 클래스 내부에서 //메소드의 매개변수와 로컬별수 사용 시 제한>

: 자바는 컴파일 시 로컬 클래스에서 사용하는 매개변수,로컬변수 값을 로컬 클래스 내부에 복사해두고 사용

: 따라서 해당 변수들에 final 특성 부여해서 사용

: final 특성 부여

= final 선언 안해도, 매개변수는 매개값 받은 그대로, 로컬 변수는 최초 초기화값 그래도 사용 가능

: 즉, 중간에 값 바꿀 수 없고 그대로 가져와서 로컬 클래스에서 사용 가능

<중첩 클래스 내부에서// 바깥 클래스를 참조> : 이름 동일한 필드,메소드 사용시

중첩 클래스 내부에서 객체 자신의 참조 : this.필드 / this.메소드

중첩 클래스 내부에서 바깥 클래스의 필드.메소드 접근

: 바깥클래스.this.필드 / 바깥클래스.this.메소드

[중첩 인터페이스] : Nested 네스티드 인터페이스

: 클래스의 멤버로 선언된 인터페이스

: 해당 클래스와 긴밀한 관계 맺는 구현 클래스 생성을 위해 중첩 인터페이스 선언

: 내부 UI 설계에서 이벤트 처리 시 多 사용

  • 인스턴스 멤버 인터페이스 (바깥 클래스 객체 생성되어야만 사용O)
  • 정적 멤버 인터페이스 (바깥 객체 생성 없이도, 바깥 클래스로 바로 접근해서 사용O)

: 주로 정적 멤버 인터페이스 사용 多

public class Button { //설계 UI 구현

    static interface OnClickListener { //중첩 인터페이스 선언 
        void onClick();
    }

    OnClickListener listener; // Button클래스의 필드 : 인터페이스 타입으로 선언

    void setOnClickListener (OnClickListener listener) { //Setter 메소드 

        this.listener = listener;
    }

    void touch() { //Button에 대한 touch() 이벤트 발생 시 호출될 메소드

        listener.onClick();
    }

< 설계 코드 해석>

Button 바깥 클래스에서 touch() 이벤트 발생 시 호출할 함수만 설계해둠

내부에 중첩 인터페이스 선언(내부 추상 메소드 선언)해두고, 매개값으로 구현 객체를 받도록

(인터페이스 타입으로 필드 선언 -> 인터페이스 타입 매개변수 Setter 메소드 호출해서 구현 객체를 매개값으로 받은 후, 인터페이스 타입 필드에 값 저장

→ touch() 메소드 실행 시. 필드에 저장된 구현 객체의 onClick() 메소드 호출 )

touch() 이벤트 발생 시 실행될 구체적인 내용은 구현 객체로 실행

09-2. 익명 객체

[익명 객체]

: 이름이 없는 객체

: 부모 객체를 상속받은 or 인터페이스를 구현한 // 익명 객체만 존재

: 명시적으로 클래스 이름을 사용하는 이유 ; 재사용성 높이기 위함(어디서든 객체 생성 가능)

: 재사용되지 않고 오직 특정 위치에서만 사용될 경우 익명 객체로 사용

[익명 자식 객체]

   **부모타입 변수 = new 부모클래스 (매개값) { ... } ;**

// 해당 부모클래스를 상속받은 자식 클래스의 내용을 { }; 와 같이 작성 후,

                          new 연산자로 익명의 자식 객체 생성하여 // 부모타입 변수에 대입한다.

(1) 필드 선언 시 : 부모타입 필드 = 익명 자식 객체 대입

(2) 메소드 내 로컬 변수 선언 시 : 부모타입 로컬 변수 = 익명 자식 객체 대입

(3) 매개변수가 부모타입인 메소드 호출 시 : 부모타입 매개변수 = 익명 자식 객체 매개값으로 대입 후 호출

[익명 구현 객체 생성]

: 구현 클래스가 재사용되지 않고, 오로지 특정 위치에서 사용될 경우 익명 구현 객체 사용

인터페이스타입 변수 = new 인터페이스() { ... } ;

//해당 인터페이스를 구현한 클래스 내부에 {}; 내용을 작성한 뒤 new연산자로 구현 객체 생성하여 인터페이스 타입 변수에 대입

(1) 필드 선언 시 //

   인터페이스 타입 필드 변수에 익명 구현 객체 초기값으로 대입

(2) 메소드 내에서 로컬변수 선언 시 //

    인터페이스 타입 로컬 변수에 익명 구현 객체 대입

(3) 매개변수가 인터페이스 타입 변수로 선언된 메소드 호출 시 //

     인터페이스 타입 매개변수에 매개값으로 익명 구현 객체 대입하여 호출

[익명 객체 내부에서 // 매개변수, 로컬변수 사용 시 제한]

: 자바는 컴파일 시 익명 객체에서 사용하는 매개변수, 로컬변수를 익명 객체 내부에 복사해두고 사용

: 컴파일러는 변수에 final특성 부여해서 값이 중간에 수정불가하도록 처리

: 매개값 받은 그대로, 초기값 선언된 그대로 각 변수를 익명 객체 내부에서 사용됨

: 중간에 값 변경 시 컴파일 에러

<<익명 구현 객체 이용한 UI 클래스>>

[UI 버튼 클래스]

public class Button {
    OnClickListener listener;

    void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
    }

    void touch() {
        listener.onClick();
    }

    static interface OnClickListener {
        void onClick();
    }
}

[익명 객체 연결한 Window 클래스]

public class Window {
    Button button1 = new Button();
    Button button2 = new Button();

    //필드 초기값으로 대입
    Button.OnClickListener listener = new Button.OnClickListener() {
        @Override
        public void onClick() {
            System.out.println("전화를 겁니다.");

    Window() {
        button1.setOnClickListener(listener);

        //매개값으로 대입
        button2.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick() {
                System.out.println("메시지를 보냅니다.");

[실행 Main클래스]

public class Main {
    public static void main(String[] args) {
        Window w = new Window();
        w.button1.touch();
        w.button2.touch();
    }
}

<<중첩 인터페이스 사용한 UI클래스>>

[중첩인터페이스 포함한 Button UI 클래스]

public class Button {
    OnClickListener listener;

    void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
    }

    void touch() {
        listener.onClick();
    }

    static interface OnClickListener {
        void onClick();
    }
}

[구현 클래스 작성-1]

public class CallListener implements Button.OnClickListener {
    @Override
    public void onClick() {
        System.out.println("전화를 겁니다.");
    }
}

[구현 클래스 작성-2]

public class MessageListener implements Button.OnClickListener {
    @Override
    public void onClick() {
        System.out.println("메시지를 보냅니다.");
    }
}

[실행 Main클래스]

728x90

'Java > [문법]_Java(자바)' 카테고리의 다른 글

11-1. java.lang 패키지  (0) 2021.08.11
ch10. 예외 처리  (0) 2021.08.05
ch08. 인터페이스  (0) 2021.08.04
ch07. 상속  (0) 2021.08.03
ch06. 클래스  (0) 2021.08.02