[이것이 자바다] CH09. 중첩 선언과 익명객체

2025. 4. 8. 12:19· JAVA/이것이 자바다
목차
  1. 중첩 클래스(Nested Class)
  2. 인스턴스 멤버 클래스
  3. 정적 멤버 클래스
  4. 로컬 클래스
  5. 바깥 멤버 접근
  6. 중첩 인터페이스
  7. 중첩 인터페이스를 사용하는 이유?
  8. 익명 객체(Anonymous Class)
  9. 익명 자식 객체
  10. 익명 구현 객체

중첩 클래스(Nested Class)


중첩클래스란 클래스 내부에 선언한 클래스를 말하는데, 중첩 클래스를 사용하면 클래스의 멤버를 쉽게 사용할 수 있고 외부에는 중첩 관계 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다는 장접이 있다.

 

선언 위치에 따른 분류 선언 위치 객체 생성 조건
멤버 클래스 인스턴스 멤버 클래스 class A {
    class B { ... }
}
A 객체를 생성해야만 B 객체를 생성할 수 있음
정적 멤버 클래스 class A {
    static class B { ... }
}
A 객체를 생성하지 않아도 B 객체를 생성할 수 있음
로컬 클래스 class A {
    void method() {
        class B { ... }
    }
}
method가 실행할 때만 B 객체를 생성할 수 있음

 

인스턴스 멤버 클래스


[ public ] class A {
	[ public | private ] class B { ... }
}

 

인스턴스 멤버 클래스 B는 주로 A 클래스 내부에서 사용되므로 private 접근 제한자를 갖는 것이 일반적이다.

B 객체는 A 클래스 내부 어디에서나 생성할 수는 없고, 인스턴스 필드값 / 생성자 / 인스턴스 메소드에서 생성할 수 있다.

A 객체가 있어야 B 객체도 생성할 수 있기 때문이다.

 

public class A {
	
    // 인스턴스 멤버 클래스
    class B {}
    
    // 인스턴스 필드 값으로 B 객체 대입
    B field = new B();
    
    // 생성자
    A() {
    	B b = new B();
    }
    
    // 인스턴스 메소드
    void method() {
    	B b = new B();
    }
}

 

 

 

인스턴스 멤버 클래스 B 내부에는 일반 클래스와 같이 필드, 생성자, 메소드 선언이 올 수 있다.

다만, 정적 필드와 정적 메소드는 Java 17부터 선언이 가능하다.

 

 

 

정적 멤버 클래스


[ public ] class A {
	[ public | private ] static class B { ... }
}

 

정적 멤버 클래스 B는 A 클래스 내부에서 사용되기도 하시만, A 클래스 외부에서 A와 함께 사용되는 경우가 많기 때문에 주로 default 또는 public 접근 제한자를 가진다.

 

로컬 클래스


class A {
    public A() {
        class B { }
    }
    
    public void method() {
        class B { }
    }
}

 

로컬 클래스는 생성자와 메소드가 실행될 동안에만 객체를 생성할 수 있으며, 내부에는 일반 클래스와 같이 필드, 생성자, 메소드 선언이 올 수 있다.

다만, 정적 필드와 정적 메소드는 Java 17부터 선언이 가능하다.

 

 

로컬 변수를 로컬 클래스에서 사용할 경우 로컬 변수는 final 특성을 갖게 되므로 값을 읽을 수만 있고 수정할 수 없게 된다.

이것은 로컬 클래스 내부에서 값을 변경하지 못하도록 제한하기 때문이다. (Java 8 이후부터는 명시적으로 final 키워드를 붙이지 않아도 된다)

 

 

바깥 멤버 접근


바깥 클래스의 멤버 접근 제한

구분 바깥 클래스의 사용 가능한 멤버
인스턴스 멤버 클래스 바깥 클래스의 모든 필드와 메소드
정적 멤버 클래스 바깥 클래스의 정적 필드와 정적 메소드

 

정적 멤버 클래스는 바깥 객체가 없어도 사용 가능해야 하므로 바깥 클래스의 인스턴스 필드와 인스턴스 메소드는 사용하지 못한다.

 

class A {
    
    int field1;
    void method1() { }
    
    static int field2;
    static void method2() { }
    
    class B {
        void method() {
            // A의 인스턴스 필드와 메소드 사용 가능
            field1 = 10;
            method1();
            
            // A의 정적 필드와 메소드 사용 가능
            field2 = 10;
            method2();
        }
    }
    
    // 정적 멤버 클래스
    static class C {
        void method() {
            // A의 인스턴스 필드와 메소드 사용 불가능
            //field1 = 10;
            //method1();
            
            // A의 정적 필드와 메소드 사용 가능
            field2 = 10;
            method2();
        }
    }
}

 

 

바깥 클래스의 객체 접근

중첩 클래스 내부에서 this는 해당 중첩 클래스의 객체를 말한다. 만약 중첩 클래스 내부에서 바깥 클래스의 객체를 얻으려면 바깥 클래스 이름에 this를 붙여주면 된다.

 

바깥클래스이름.this -> 바깥객체

 

 

class A {
    String field = "A-field";
    
    void method() {
        System.out.println("A-method");
    }
    
    class B {
        String field = "B-field";
        
        void method() {
            System.out.println("B-method");
        }
        
        void print() {
            // B 객체의 필드와 메소드 사용
            System.out.println(this.field);
            this.method();
            
            // A 객체의 필드와 메소드 사용
            System.out.println(A.this.field);
            A.this.method();
        }
    }
}

 

 

중첩 인터페이스


중첩 인터페이스는 클래스의 멤버로 선언된 인터페이스를 말한다.

 

class A {
	[ public | private ] [ static ] interface B {
    	// 상수 필드
        // 추상 메소드
        // 디폴트 메소드
        // 정적 메소드
    }
}

 

 

 

중첩 인터페이스를 사용하는 이유?


중첩 인터페이스는 Android와 같은 UI 프로그램에서 이벤트를 처리할 목적으로 많이 활용된다.

 

모바일에서는 버튼 클릭이나 터치같은 이벤트 처리가 자주 필요하다. 따라서, 클래스에 중첩 인터페이스로 EventListener를 선언해두면 다양한 이벤트를 관리하기 용이해진다.

 

예를 들어보자.

 

다음과 같이 중첩 인터페이스를 갖는 Button이라는 객체를 생성해두면, 이를 구현하는 다양한 버튼과 기능을 만들어낼 수 있다.

당장 스마트폰을 봤을 때 상상할 수 없을 정도로 많은 터치 이벤트가 있는 걸 생각해보면 필요한 기능이 아닐 수 없다.

public class Button {
	// 정적 멤버 인터페이스
	public static interface ClickListener {
    	// 추상 메소드
        void onClick();
    }
    
    private ClickListener clickListener;
    
    
    // setter 생성
    public void setClickListener(ClickListener clickListener) {
    	this.ClickListener = clickListener;
    }
    
	// Button이 클릭되었을 때 실행
    public void click() {
    	this.clickListener.onClick(); 
    }
}
public class ButtonExample {
    public static void main(String[] args) {
        Button btnOk = new Button();

        // Ok 버튼 클릭 이벤트를 처리할 ClickListener 구현 클래스(로컬 클래스)
        class OkListener implements Button.ClickListener {
            @Override
            public void onClick() {
                System.out.println("Ok 버튼을 클릭했습니다.");
            }
        }

        // Ok 버튼 객체에 ClickListener 구현 객체 주입
        btnOk.setClickListener(new OkListener());

        // Ok 버튼 클릭하기
        btnOk.click();

        // ==========================================
        Button btnCancle = new Button();

        // Cancle 버튼 클릭 이벤트를 처리할 ClickListener 구현 클래스(로컬 클래스)
        class CancleListener implements Button.ClickListener {
            @Override
            public void onClick() {
                System.out.println("Cancle 버튼을 클릭했습니다.");
            }
        }

        // Cancle 버튼 객체에 ClickListener 구현 객체 주입
        btnCancle.setClickListener(new CancleListener());

        // Cancle 버튼 클릭하기
        btnCancle.click();
    }
}



 

익명 객체(Anonymous Class)


익명 객체는 이름이 없는 객체를 말한다. 명시적으로 클래스를 선언하지 않기 때문에 쉽게 객체를 생성할 수 있다는 장점이 있다.

익명 객체는 필드값, 로컬 변수값, 매개변수값으로 주로 사용된다.

 

익명 객체는 클래스를 상속하거나 인터페이스를 구현해야만 생성할 수 있다.

 

클래스를 상속해서 만들 경우 익명 자식 객체라고 하고, 인터페이스를 구현해서 만들 경우 익명 구현 객체라고 한다.

 

익명 자식 객체


new 부모생성자(매개값, ...) {
	// 필드
    // 메소드
}

 

 

익명 구현 객체


중첩 인터페이스와 마찬가지로 Android같은 UI 프로그램에서 많이 사용된다.

new 인터페이스() {
	// 필드
    // 메소드
}

 

저작자표시 비영리 (새창열림)

'JAVA > 이것이 자바다' 카테고리의 다른 글

[이것이 자바다] CH08. 인터페이스, 확인문제  (0) 2025.04.08
[이것이 자바다] CH04. 조건문과 반복문, 확인문제  (1) 2025.03.17
[이것이 자바다] CH03. 연산자, 확인문제  (0) 2025.03.16
[이것이 자바다] CH02. 변수와 타입, 확인문제  (0) 2025.03.16
[이것이 자바다] CH01. 자바 시작하기, 확인문제  (3) 2025.03.16
  1. 중첩 클래스(Nested Class)
  2. 인스턴스 멤버 클래스
  3. 정적 멤버 클래스
  4. 로컬 클래스
  5. 바깥 멤버 접근
  6. 중첩 인터페이스
  7. 중첩 인터페이스를 사용하는 이유?
  8. 익명 객체(Anonymous Class)
  9. 익명 자식 객체
  10. 익명 구현 객체
'JAVA/이것이 자바다' 카테고리의 다른 글
  • [이것이 자바다] CH08. 인터페이스, 확인문제
  • [이것이 자바다] CH04. 조건문과 반복문, 확인문제
  • [이것이 자바다] CH03. 연산자, 확인문제
  • [이것이 자바다] CH02. 변수와 타입, 확인문제
Anna-Jin
Anna-Jin
Anna-Jin
내일 한걸음 더
Anna-Jin
TOTAL
TODAY
YDAY
  • CATEGORY (212)
    • Project (0)
      • Zero2One.Dev (0)
    • Algorithm (40)
      • Leetcode (20)
      • Programmers (1)
      • CODETREE (0)
      • Baekjoon (7)
      • etc (12)
    • JAVA (42)
      • JAVA (20)
      • 점프투자바 (16)
      • 이것이 자바다 (6)
    • Spring boot (20)
    • Database (9)
    • CS (11)
    • Study (80)
      • Trouble Shooting (11)
      • TIL (50)
      • WIL (11)
      • Etc (8)
    • Review (10)
    • Projects (0)
      • Blog (0)

BLOG MENU

  • GITHUB
  • RESUME

공지사항

POPULAR POSTS

태그

  • 항해99
  • Wil
  • Java
  • til
  • 자바
  • 알고리즘
  • 자료구조
  • 코딩테스트
  • JPA
  • 확인문제
  • Algorithm
  • 트러블슈팅
  • spring boot
  • 삽질로그
  • 리트코드
  • 이것이 자바다
  • 코테
  • leetcode
  • 회고록
  • MySQL

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
Anna-Jin
[이것이 자바다] CH09. 중첩 선언과 익명객체
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.