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

중첩 클래스 (nested class)

  • 클래스 내부에 선언한 클래스
  • 중첩 클래스를 사용하면 두 클래스의 멤버들을 쉽게 접근할 수 있고 외부에는 불필요한 관계 클래스를 감춤으로서 코드의 복잡성을 줄일 수 있음

 

중첩 인터페이스 nested interface

  • 인터페이스를 클래스 내부에서 선언하는 경우
  • 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해서 사용

 

중첩 클래스

  • 멤버 클래스: 클래스의 멤버로서 선언되는 중첩 클래스
  • 로컬 클래스: 생성자 또는 메소드 내부에서 선언되는 중첩 클래스
  • 멤버 클래스는 클래스나 객체가 사용 중이라면 언제든지 재사용이 가능하지만 로컬 클래스는 메소드 실행할 때만 사용되고 메소드가 종료되면 없어짐

 

중첩 클래스 바이트 코드 파일 => A $ B . class
  • A는 바깥 클래스, B는 멤버 클래스

 

로컬 클래스 바이트 코드 파일 => A $1 B .class
  • A는 바깥 클래스, B는 로컬 클래스

 

인스턴스 멤버 클래스

  • static 키워드 없이 중첩 선언된 클래스
  • 인스턴스 멤버 클래스는 인스턴스 필드와 메소드만 선언이 가능하고 정적 필드와 메소드는 선언할 수 없음

 

class A {
	/**인스턴스 멤버 클래스**/
    class B {
    	B() {} //생성자
        int field1; //인스턴스 필드
        //static int field2; // 정적필드 (x)
        void method1() {} //인스턴스 메소드
        //static void method2() {} // 정적 메소드 (x)
        }
 }

 

정적 멤버 클래스

  • static 키워드로 선언된 클래스
  • 모든 종류의 필드와 메소드를 선언 할 수 있음
class A {
	/**정적 멤버 클래스**/
    static class C {
    	C() {} //생성자
        int field1; //인스턴스 필드
        static int field2; // 정적필
        void method1() {} //인스턴스 메소드
        static void method2() {} // 정적 메소드
        }
 }

 

 

로컬 클래스

메소드 내에서 중첩 클래스 선언

  • 로컬 클래스는 접근 제한자 및 static을 붙일 수 없음
  • 로컬 클래스는 메소드 내부에서만 사용되므로 접근을 제한할 필요가 없음
  • 로컬 클래스 내부에는 인스턴스 필드와 메소드만 선언할 수 있음
  • 정적 필드와 메소드는 선언할 수 없음
  • 로컬 클래스는 메소드가 실행될 때 메소드 내에서 객체를 생성하고 사용해야 함

 

중첩 클래스의 접근 제한

  • 멤버 클래스 내부에서 바깥 클래스의 필드와 메소드에 접근할 때는 제한이 있음
  • 메소드의 매개변수나 로컬 변수를 로컬 클래스에서 사용할 때도 제한이 있음

 

바깥 필드와 메소드에서 사용 제한

  • 바깥 클래스에서 인스턴스 멤버 클래스를 사용할 때 제한
  • 인스턴스 멤버 클래스는 바깥 클래스의 인스턴스 필드의 초기값이나 인스턴스 메소드에서 객체를 생성할 수 있음
  • 정적 필드의 초기값이나 정적 메소드에서는 객체를 생성할 수 없음
  • 정적 멤버 클래스는 모든 필드의 초기값이나 모든 메소드에서 객체를 생성할 수 있음

 

멤버 클래스에서 사용제한

  • 멤버 클래스가 인스턴스 또는 정적으로 선언됨에 따라 멤버 클래스 내부에서 바깥 클래스의 필드와 메소드에 접근할 때에도 제한이 있음
  • 인스턴스 멤버 클래스 안에서는 바깥 클래스의 모든 필드와 모든 메소드에 접근 가능
  • 정적 멤버 클래스 안에서는 바깥 클래스의 정적필드와 메소드에만 접근할 수 있고 인스턴스 필드와 메소드에는 접근할 수 없음

 

로컬클래스에서 사용 제한

  • 메소드의 매개 변수나 로컬 변수를 로컬 클래스에서 사용할 때 제한
  • 로컬 클래스의 객체는 메소드 실행이 종료되면 없어지는 것이 일반적이지만 로컬 스레드 객체를 사용하면 계속 실행상태로 존재
  • 매개 변수나 로컬 변수가 수정되어 값이 변경되면 로컬 클래스에 복사해둔 값과 달라지므로 문제를 해결하기 위해 매개변수나 로컬 변수를 final로 선언할것을 요구 -> 자바 8부터는 final 선언을 하지 않아도 값이 수정될 수 없도록 final 특성을 부여함

 

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

  • 중첩 클래스에서 this 키워드를 사용하면 바깥 클래스의 객체 참조가 아니라, 중첩 클래스의 객체 참조가 됨
  • 중첩 클래스 내부에서 this.필드, this.메소드()로 호출하면 중첩 클래스의 필드와 메소드가 사용됨
  • 중첩 클래스 내부에서 바깥크 ㄹ래스의 객체 참조를 얻으려면 바깥 클래스의 이름을 this 앞에 붙여주면 됨
바깥클래스.this.필드;
바깥클래스.this.메소드();

 

중첩 인터페이스

  • 클래스 멤버로 선언된 인터페이스
  • 인터페이스를 클래스 내부에서 선언하는 이유는 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해서임
  • 중첩 인터페이스는 인스턴스 멤버 인터페이스와 정적멤버 인터페이스 모두 가능
  • 인스턴스 멤버 인터페이스는 바깥 클래스의 객체가 있어야 사용 가능
  • 정적 멤버 인터페이스는 바깥 클래스의 객체 없이 바깥 클래스만으로 바로 접근 가능
  • UI 프로그래밍에서 이벤트를 처리할 목적으로 많이 활용
class A {
	[static] interface I {
    void method();
    }
}

 

확인문제

  • 인스턴스 멤버 클래스는 바깥 클래스의 객체가 있어야 사용될 수 있다. (o)
  • 정적 멤버 클래스는 바깥 클래스의 객체가 없어도 사용될 수 있다 (o)
  • 인스턴스 멤버 클래스는 내부에는 바깥 클래스의 필드와 메소드를 사용할 수 있다. (o)
  • 정적 멤버 클래스 내부에는 바깥 클래스의 인스턴스 필드를 사용할 수 있다. (x)
  • 로컬 클래스는 생성자 또는 메소드 내부에 선언된 클래스를 말한다. (o)
  • 로컬클래스도 필드와 생성자를 가질 수 있다. (o)
  • 로컬 클래스는 static 키워드를 이용해서 정적 클래스로 만들 수 있다. (x)
  • final 특성을 가진 매개 변수나 로컬 변수만 로컬 클래스 내부에서 사용할 수 있다. (o)

+ Recent posts