ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 중첩 클래스(Nested Class)와 중첩 인터페이스(Nested Interface)
    JAVA 2023. 3. 10. 12:00

    중첩 클래스

    클래스 내부에 선언된 다른 클래스

     

    • 특정 클래스만 관계를 맺을 경우에 사용
    • 클래스의 멤버 사용이 편리하다.
    • 외부에서는 중첨 관계의 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다.
    • 바깥 클래스를 컴파일하면 중첩 클래스에 대한 별도의 바이트코드 파일(.class)이 생성된다.
      중첩 클래스의 바이트코드 파일은 "$" 앞에 외부 클래스가 기록된다.
      바깥클래스명$중첩클래스명.class


    인스턴스 멤버 클래스

    클래스의 인스턴스 멤버로 선언된 중첩 클래스

     

    class 외부클래스 {
        [public | privateclass 멤버클래스 { ... }
    }

     

    • 일반적으로 private 접근 제한으로 설정하여 바깥 클래스 내부에서만 사용한다.
    • 객체 생성은 바깥 클래스의 인스턴스 필드 값, 생성자, 인스턴스 메소드에서 가능하다.

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

     

    • 바깥 클래스 객체가 먼저 생성되어야 객체를 생성할 수 있다.

     

    A a = new A();
    A.B b = a.new B();

     

    • 인스턴스 멤버 클래스는 일반 클래스와 동일한 멤버(필드, 생성자, 메소드)를 가질 수 있다.
      단, 정적 필드와 정적 메소드는 Java 17부터 지원한다.

     


    정적 멤버 클래스

    클래스 내부에 static 키워드로 선언된 중첩 클래스

     

    class 외부클래스 {
        [public | privatestatic class 멤버클래스 { ... }
    }

     

     

    • 바깥 클래스 외부에서 사용되는 경우가 많아서 주로 default 또는 public 접근 제한을 부여한다.
    • 정적 멤버 클래스 객체는 바깥 클래스의 내부 어디든지 생성할 수 있다.

     

    public class A {
        //인스턴스 멤버 클래스
        static class B {}
     
        //인스턴스 필드 값으로 B 객체 대입
        B field1 = new B();
     
        //정적 필드 값으로 B 객체 대입
        static B field2 = new B();
     
        //생성자
        A() {
            B b = new B();
        }
     
        //인스턴스 메소드
        void method1() {
            B b = new B();
        }
     
        //정적 메소드
        static void method2() {
            B b = new B();
        }
    }

     

    • 외부에서 선언된 클래스 객체를 생성하지 않고 객체를 생성할 수 있다.

     

    A.B b = new A.B();

     

     


    로컬 클래스

    생성자 또는 메소드 내부에 선언된 중첩 클래스

     

    class 바깥클래스 {
        리턴타입 메소드() {
            class 로컬클래스 { ... }
        }
    }

     

    • 클래스를 선언한 생성자 또는 메소드가 실행될 때만 객체를 생성할 수 있다.
    • 로컬 클래스도 필드, 생성자, 메소드를 가질 수 있다.
      정적 필드와 정적 메소드는 Java 17부터 지원

     

    //바깥 클래스
    public class A {    
        
        //메소드
        void useB() {    
            
            //로컬 클래스
            class B {
     
                //인스턴스 필드
                int field1 = 1;
     
                //정적 필드(Java 17부터 허용)
                static int field2 = 2;
     
                //생성자
                B() {
                    System.out.println("B-생성자 실행");
                }
     
                //인스턴스 메소드
                void method1() {
                    System.out.println("B-method1 실행");
                }
     
                //정적 메소드(Java 17부터 허용)
                static void method2() {
                    System.out.println("B-method2 실행");
                }
            }
            
            //로컬 객체 생성
            B b = new B();
            
            //로컬 객체의 인스턴스 필드와 메소드 사용
            System.out.println(b.field1);
            b.method1();
            
            //로컬 클래스의 정적 필드와 메소드 사용(Java 17부터 허용)
            System.out.println(B.field2);
            B.method2();
        }
    }

     

    로컬 변수

    • 생성자나 생성자 내부, 메소드의 매개변수 또는 메소드 내부에서 선언된 변수
    • 로컬 클래스 내부에서 로컬 변수는 final 특성을 갖게 되어 값을 변경할 수 없다.
      Java 7 이전에는 final 키워드 필수
      Java 8 이후부터 final 키워드 생략 가능(final 특성을 가진다는 것을 명시하기 위해 사용)

     


    바깥 멤버 접근


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

    종류 정적 필드 정적 메소드 인스턴스 필드 인스턴스 메소드
    인스턴스 멤버 클래스 O O O O
    정적 멤버 클래스 O O X X

     

    • 정적 멤버 클래스는 바깥 객체가 없어도 사용 가능해야 하므로 바깥 클래스의 인스턴스 멤버는 접근할 수 없다.

     


    바깥 클래스의 객체 접근

    • 중첩 클래스 내부에서 this는 해당 중첩 클래스 객체를 의미함.
    • 바깥 클래스 객체는 바깥 클래스 이름까지 명시한 this로 호출한다.

     

    //바깥 클래스 A
    public class A {
     
        //A 인스턴스 필드 선언
        String field = "A class";
        
        //A 인스턴스 메소드 선언
        void method(String field) { 
            
            //A 인스턴스 필드 호출
            System.out.println(this.field);
            System.out.println(field);
        }
        
        //인스턴스 멤버 클래스 A
        class B {
            
            //B 인스턴스 필드 선언
            String field = "B class";
        
            //B 인스턴스 메소드 선언
            void method() { 
                
                //A 인스턴스 메소드와 B 인스턴스 필드 호출
                A.this.method(this.field);
            }
        }
    }

     

     


    중첩 인터페이스

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

     

    • 해당 클래스와 긴밀한 관계를 맺는 구현 객체를 만들기 위해 사용

     

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

     

    • 안드로이드를 포함한 UI 프로그램에서 이벤트를 처리할 때 많이 사용

     

    'JAVA' 카테고리의 다른 글

    System 클래스  (0) 2023.03.13
    Object 클래스  (0) 2023.03.13
    제네릭(Generic)  (0) 2023.03.02
    컬렉션 자료구조(Collection Data Structure)  (0) 2023.03.02
    Java 표준 라이브러리  (0) 2023.03.02
Designed by Tistory.