본문 바로가기

개발(합니다)/Java&Spring

[java-기초-09] 중첩 클래스와 중첩 인터페이스

반응형

충첩 클래스와 중첩 인터페이스란?

  • 클래스 내부에 선언한 클래스를 말하며 중첩 클래스를 사용하면 두 클래스의 멤버들을 서로 쉽게 접근할 수 있다는 장점과 외부에는 불필요한 관계 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다.
    class ClassName {
        class NestedClassName {
        }
    }
  • 중첩 클래스
    class ClassName {
        interface NestedInterfaceName {
        }
    }
  • 중첩 인터페이스

중첩 클래스

  • 클래스의 멤버로 선언되는 중첩 클래스는 멤버 클래스라고 한다.
  • 메서드 내부에 선언되는 중첩 클래스는 로컬 클래스라고 한다.
    class A {
        class B { // 멤버 클래스
        }
        static class C { // 정적 멤버 클래스
        }
        void method() {
            class D { // 로컬 클래스
            }  
        }
    } 
  • 멤버 클래스 바이트 코드 파일명 : A$B.class
  • 로컬 클래스 바이트 코드 파일명 : A$1B.class

인스턴스 멤버 클래스

    class A {
        // 인스턴스 멤버 클래스 
        class B {
            B() {}  // 생성자
            int field1; // 인스턴스 필드
            // static int field2; // 정적필드 사용 불가
            void method1() {} // 인스턴스 메서드 
            //static void method2() {} // 정적 메서드 사용 불가
        }
    }
    public static void main(String args[]) {
        A a = new A(); 
        A.B b = a.new B(); // a 객체를 생성하고 B객체를 생성해야 한다.
        b.field1 = 3;
        b.method1();
    }

정적 멤버 클래스

    class A {
        // 정적 멤버 클래스 
        static class C {
            C() {}  // 생성자
            int field1; // 인스턴스 필드
            static int field2; // 정적필드 
            void method1() {} // 인스턴스 메서드 
            static void method2() {} // 정적 메서드
        }
    }
    public static void main(String args[]) {
        A.C c = new A.C(); // A 객체 생성 없이 C객체를 생성할 수 있다.
        c.field1 = 3;
        c.method1();
    }

로컬 클래스

    void method() {
        // 로컬 클래스 
        class D {
            D() {}  // 생성자
            int field1; // 인스턴스 필드
            // static int field2; // 정적필드 사용 불가
            void method1() {} // 인스턴스 메서드 
            // static void method2() {} // 정적 메서드 사용 불가
          }
        D d = new D(); // 메서드가 실행될 때 메서드 내에서 객체를 생성하고 사용해야 한다.
        d.field1 = 3;  // 주로 스레드를 사용할 때 로컬 클래스를 사용한다.
        d.method1();
    }

    void method2() {
        class DownloadThread extends Thread { ... }
        DownloadThread thread = new DownloadThread();
        thread.start();
    }

중첩 클래스의 접근 제한

  • 인스턴스 필드에서 초기값이나 인스턴스 메서드에서 객체를 생성할 수 있으나 정적 필드의 초기값이나 정적 메서드에서는 객체를 생성할 수 없다.
  • 인스턴스 멤버 클래스 안에서는 바깥 클래스의 모든 필드와 모든 메서드에 접근할 수 있지만, 정적 멤버 클래스안에서는 바깥 클래스의 정적 필드와 메서드에만 접근할 수 있고 인스턴스 필드와 메서드는 접근할 수 없다.
  • 로컬 클래스 내부에서는 바깥 클래스의 필드나 메서드를 제한 없이 사용할 수 있는데 로컬 클래스의 객체는 메서드 실행이 끝나도 힙 메모리에 존재해서 계속 사용될 수 있게 된다. 이로 인해 매개 변수나 로컬 변수는 메서드 실행이 끝나면 스택 메모리에서 사라지기 때문에 로컬 객체에서 사용할 경우 문제가 발생한다.
    • 로컬 클래스에서 사용 가능한 것은 final로 선언 된 매개변수와 로컬 변수뿐이다.
    • final 키워드가 있다면 로커 ㄹ클래스의 메서드 내부에 지역 변수로 복사되지만, final 키워드가 없다면 로컬 클래스의 필드로 복사된다.
    • 로컬 클래스에서 사용된 매개변수와 로컬 변수는 모두 final 특성을 갖는다는 것만 알면 된다.

중첩 클래스에서 바깥 클래스 참조 얻기

  • 중첩 클래스에서 this 키워드를 사용하면 바깥 클래스의 객체 참조가 아니라 중첩 클래스의 객체 참조가 된다.
  • 바깥 클래스의 객체 참조를 얻으려면 "바깥클래스.this.필드", "바깥클래스.this.메서드()"를 사용한다.

중첩 인터페이스

  • 인터페이스의 성질을 유지하고 중첩 클래스와 동일

익명 객체

  • 익명 객체의 성질을 유지하고 중첩 클래스와 동일
반응형

'개발(합니다) > Java&Spring' 카테고리의 다른 글

[java-기초-06-부록] 애너테이션  (4) 2021.01.11
[java-기초-10] 예외 처리  (0) 2021.01.08
[java-기초-08] 인터페이스  (0) 2021.01.06
[java-기초-07] 상속  (0) 2021.01.05
[java-기초-06] 클래스  (0) 2021.01.04