JAVA/공부

이너 클래스와 이너 인터페이스

GaeGim 2022. 7. 11. 23:39
반응형

이너 클래스 : 클래스 내부에 포함되는 클래스

이너클래스는 인스턴스 멤버 이너 클래스, 정적 이너 클래스, 지역 이너 클래스, 익명 이너 클래스로 나뉠 수 있다.

 

 

  • 인스턴스 이너 클래스

객체 내부에 멤버의 형태로 존재.

자신을 감싸고 있는 아우터 클래스의 모든 접근 지정자의 멤버에 접근 가능하다.

 

· 바이트 코드 표현

아우터 클래스 : 아우터 클래스.class

이너 클래스 : 아우터 클래스$이너 클래스.class

 

※ 이너 클래스는 단독으로 사용이 불가하고 반드시 아우터 클래스를 이용해야만 사용할 수 있다.

 

· 객체 생성하기

이너 클래스의 객체를 생성하려면 아우터 클래스의 객체를 먼저 생성해야 한다. 아우터 클래스 객체의 참조변수를 통해 객체 내부 이너 클래스의 생성자를 아래와 같이 호출할 수 있다.

아우터 클래스 아우터클래스의 참조변수 = new 아우터 클래스();
아우터클래스.이너클래스 이너클래스의 참조변수 = 아우터 클래스 참조변수.new이너클래스();

※ 이너 클래스의 객체 자료형은 아우터클래스.이너클래스다.

 

만약 아우터 클래스의 필드나 메서드의 이름이 같은 게 이너 클래스 안에 정의돼 있을 때, 이너 클래스의 내부에서 누구의 필드, 메서드가 참조될까? 이너클래스의 것이 참조된다. this 키워드가 자동으로 추가되기 때문이다.

 

이너클래스 내부에서 아우터 클래스 멤버를 참조하고 싶다면 '아우터 클래스명.this.'를 붙여 명시하면 된다.

 

※ 이너 클래스 메서드 내 참조변수 없이 멤버를 사용하면 컴파일러는 일단 this.를 붙여 멤버를 찾고 만약 멤버가 없으면 '아우터클래스.this'를 붙인 후 아우터 클래스의 멤버를 검색해 실행한다.

 

 

 

  • 정적 멤버 이너 클래스

이너 클래스 앞에 static 키워드가 붙어 있는 클래스.

아우터 클래스의 정적멤버에만 접근할 수 있는데 이는 정적 특성이지 이너 클래스의 특성이 아니다.

아우터 클래스의  객체를 생성하지 않아도 정적 이너 클래스의 객체를 이용할 수 있어야 하므로 정적 멤버만 사용 가능.

 

· 객체 생성하기

정적 이너 클래스도 정적 멤버이므로 객체 생성 없이 클래스명으로 바로 접근할 수 있다.

아우터클래스.이너클래스 이너클래스참조변수 = new 아우터클래스.이너클래스();

 

 

 

  • 지역 이너 클래스

클래스 멤버가 아닌 메서드 내에 정의되는 클래스.

지역변수처럼 메서드 내에서만 사용할 수 있어서 메서드가 호출되야 메모리에 로딩됨.

지역 이너 클래스는 정적 클래스로 지정 불가하다.

 

//지역 클래스 컴파일 시 생성되는 클래스명
아우터클래스 $ 숫자 지역이너클래스 .class

지역 이너 클래스는 메소드 내에서만 정의하고 사용할 수 있어 여러 메서드에서 동일한 이름의 지역 이너 클래스가 있을 수 있어 숫자가 추가된다. 동일 지역 클래스명이 있을 땐 숫자가 +1된다.

 

 

· 객체 생성하기

아우터 클래스 멤버를 접근 지정자 상관없이 사용 가능하고

자신이 정의된 메서드 지역변수도 클래스 내부에서 사용가능

 

지역변수 사용 시 반드시 해당 지역변수는 final로 선언돼야 함.

final 작서 안할 시 컴파일러가 강제로 해당 지역변수 final 추가해줌.

 

클래스가 정의된 메서드 내부에서만 객체를 생성할 수 있다.

지역이너클래스 지역이너클래스참조변수 = new 지역 이너 클래스();

 

 

 

  • 익명 이너 클래스

이름을 알 수 없는 이너 클래스

 

정의된 위치에 따라 분류할 수 있다.

- 인스턴스 익명 이너 클래스 : 클래스 중괄호 바로 아래에 있을 때

- 지역 익명 이너 클래스 : 메서드 내부에서 사용했을 때

 

 

interface C {
    public abstract void bcd();
}


class B implements C {
    public void bcd() {
    }
    public void cde() {
    }
}
B b = new B();
b.bcd();
b.cde();


C c = new C() {
    public void bcd() {
    	cde();
    }
    public void cde() {
    }
};
c.bcd();
c.cde();	//호출 불가 - C타입에 없음

 

클래스 B처럼 자식 클래스 타입으로 객체 선언하고 생성하면 오버라이팅된 메서드와 추가 메서드 모두 사용 가능하다. 메서드 모두 클래스 내부에 정의되어 있거 참조 변수가 B타입이기 때문에 메서드를 모두 호출할 수 있다.

반면 익명 이너 클래스는 항상 부모 타입으로만 선언할 수 있어 추가 정의한 메서드는 항상 호출할 수 없다.

 

 

· 익명 이너 클래스를 활용한 인터페이스 타입의 입력매개변수 전달

입력매개변수로 사용될 인터페이스 A타입의 객체를 생성해야 한다. 인터페이스로는 객체를 생성할 수 없어 인터페이스를 구현한 자식 클래스의 객체가 전달되어야 한다.

 

위의 전달법

1. 인터페이스를 상속한 자식 클래스를 직접 지정

-1. 자식 클래스 생성자를 이용해 생성한 객체를 인터페이스 타입 참조변수에 저장하고 입력매개변수로 참조변수를 넘겨         주는 방식

-2. 메서드 입력매개변수 위치에서 바로 자식 클래스 생성자로 객체를 생성하면 생성된 객체의 참조값이 메소드로 전달.

 

2. 익명 이너 클래스를 이용해 메서드 입력매개변수로 객체 전달

-1. 익명 이너 클래스로 객체 생성하고 객체를 참조하는 참조변수를 메서드의 입력매개변수에 전달.

-2. 참조 변수 대입하지 않고 메서드 입력매개변수 자리에 바로 익명 이너 클래스 객체 생성해 전달.

 

둘 중 무슨 방법으로 할 지는 객체를 몇 번 생성하는 지로 정하면 좋을 것이다.

 

 

 

  • 이너 인터페이스

사용자 인터페이스의 이벤트 처리에 많이 쓰인다.

 

※ 리스너 : 사용자 인터페이스에서 이벤트를 감지하는 인터페이스

 

특징 : 정적 이너 인터페이스만 존재할 수 있다.

따라서 이너 인터페이스 앞에 static 제어자를 생략하면 컴파일러가 자동으로 추가해준다.

 

컴파일 하면,

아우터클래스명$이너인터페이스명.class형태로 바이트 코드가 생성된다.

 

이너 인터페이스도 자체적으로는 객체를 생성할 수 없다. 

-> 객체 타입을 아우터클래스명.이너인터페이스명으로 해서,

    인터페이스를 상속한 자식 클래스를 생성한 후 생성자로 객체를 만들거나 익명 이너 클래스로 객체 생성해야 함.

 

 

반응형

'JAVA > 공부' 카테고리의 다른 글

스레드  (0) 2022.07.11
예외 처리  (0) 2022.07.11
자바 제어자-2  (0) 2022.07.02
클래스 상속과 다형성  (0) 2022.07.02
자바 제어자-1  (0) 2022.07.02