본문 바로가기

Java

13 -1 장 이너 클래스

- 이너클래스(inner class)

  - 클래스 내부에 포함 

 

- 종류 

 - 인스턴스 멤버 이너 클래스 

 - 정적 멤버 이너 클래스 

 - 지역 이너 클래스 

 

class A { //아우터 클래스 
	class B { //인스턴스 멤버 클래스
    	//...
     }
     
     static class C { //정적 멤버 클래스
     	//...
     }
     
     void abc() {
     	class D { //지역 이너 클래스
        	//...
        }
    }
}

 

 

 1. 인스턴스 멤버 이너 클래스 

 

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

  - 아우터 클래스(outer class)의 모든 접근 지정자의 멤버에 접근 가능 

  - 소스파일 (.java)이 1개라 하더라도 컴파일을 수행하면 각 클래스별로 바이트 코드(.class)파일 생성

  -  '아우터 클래스.class' 

  - ' 아우터 클래스$이너 클래스.class'

  -  독립적으로 사용할 수 없고, 반드시 아우터 클래스를 이용해야만 사용 가능

class 아우터 클래스 {
	class 이너 클래스 {
    	//...
     }
}

 

 1) 인스턴스 이너 클래스 객체 생성하기 

 

  - 이너 클래스의 객체를 생성하기 위해서는 먼저 아우터 클래스의 객체를 생성 

  - 이후 생성한 아우터 클래스 객체의 참조 변수를 이용해 객체 내부에 있는 이너 클래스의 생성자 호출

아우터 클래스 아우터 클래스 참조 변수 = new 아우터 클래스();
아우터 클래스.이너 클래스 참조 변수 = 아우터 클래스 참조 변수.new 이너 클래스();
class A {
	class B {
    }
}

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

 - 이너 클래스 객체의 자료형 A.B

 - 생성되는 바이트 코드  A$B.class

package InnerClass;

class A {
	public int a = 3;
	protected int b = 4;
	int c = 5;
	private int d = 6;
	void abc() {
		System.out.println("A 클래스 메서드 abc()");
	}
	
	//인스턴스 이너 클래스 
	class B {
		void bcd() {
			//아우터 클래스의 필드 사용 
			// 아우터 클래스의 모든 멤버를 접근 지정자와 상관없이 사용가능
			System.out.println(a);
			System.out.println(b);
			System.out.println(c);
			System.out.println(d);
			//아우터 클래스의 메서드 호출
			abc();
		}
	}
}
public class InnerClass {
	public static void main(String[] args) {
		//아우터 클래스 객체 생성
		A a = new A();
		//멤버 사용
		A.B b = a.new B();
		b.bcd();
	}
}

 

2) 아우터 클래스의 객체 참조하기 

 

 - 이너 클래스 내부에서 this의 의미는 이너 클래스 자신

 - 이너 클래스 내부에서 아우터 클래스의 멤버 참조   

   -> '아우터 클래스명.this'를 명시적으로 붙여 사용 

 

ex)

 - 클래스 B 내부의 메서드에서 a와 같이 참조 변수 없이 멤버 사용 or this.a

   -> B 클래스의 필드 a

 -  아우터 클래스의 필드 a를 참조하려면 

   -> A.this.a와 같이 사용

 

package InnerClass;

class A {
	int a = 3;
	int b = 4;
	void abc() {
		System.out.println("A 클래스 메서드");
	}
	//인스턴스 이너 클래스 정의 
	class B {
		int a = 5;
		int b =6;
		void abc() {
			System.out.println("B 클래스 메서드");
		}
		void bcd() {
			//이너 클래스의 멤버 호출 또는 사용 
			System.out.println(a);
			System.out.println(b);
			abc();
			
			//아우터 클래스의 멤버 호출 또는 사용
			System.out.println(A.this.a);
			System.out.println(A.this.b);
			A.this.abc();
		}
	}
}
public class InnerClass {
	public static void main(String[] args) {
		//아우터 클래스 객체 생성
		A a = new A();
		
		//이너 클래스 객체 생성
		A.B b = a.new B();
		b.bcd();
	}
}

 

2. 정적 멤버 이너 클래스 

 

 - 이너 클래스 앞에 static 키워드가 포함된 이너 클래스 

 - 아우터 클래스의 정적 멤버에만 접근 가능 (Static 특성)

 

 1) 정적 이너 클래스 객체 생성하기 

  

 - 컴파일 이후 '아우터 클래스.class' '아우터 클래스$이너 클래스.class'의 바이트 코드 파일 생성

 - 정적 멤버이므로 클래스명으로 바로 접근 가능 

 - 아우터 클래스의 객체를 생성하지도 않고 바로 사용 가능 

 

아우터 클래스.이너 클래스 이너 클래스 참조 변수 = new 아우터 클래스.이너 클래스();
class A {
	static class B{
    }
}

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

class A {
	int a = 3;
	static int b = 4;
	void method1() {
		System.out.println("instance method");
	}
	static void method2() {
		System.out.println("static method");
	}
	//정적 이너 클래스 
	static class B {
		void bcd() {
			//필드 사용
			//System.out.println(a); 정적 이너 클래스는 아우터 클래스의 정적 멤버만 사용 가능
			System.out.println(b);
			//메서드 호출 
			//method1();
			method2();
		}
	}
}

public class InnerClass {
	public static void main(String[] args) {
		//정적 이너 클래스의 객체 생성
		A.B b = new A.B();
		//메서드 호출
		b.bcd();
	}
}

 

3. 지역 이너 클래스 

 

 - 메서드 내에서 정의되는 클래스 

 - 지역 변수처럼 정의된 메서드 내부에서만 사용 가능

 - 선언 이후 바로 객체를 생성해 사용하며, 메서드가 호출될 때만 메모리에 로딩 

 - 지역 이너 클래스는 정적 클래스로 지정 불가 

 - ' 아우터 클래스$ + 숫자 + 지역 이너 클래스.class'

   -> 숫자가 포함되는 이유 : 여러 개의 메서드에서 동일한 이름의 지역 이너 클래스를 생성할 수도 있기 때문

 

 1) 이너 클래스 객체 생성하기 

 

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

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

  -  지역 변수를 사용할 때는 반드시 해당 지역 변수가 final로 선언돼야 함

 

지역 이너 클래스 지역 이너 클래스 참조 변수  = new 지역 이너 클래스();
class A {
	void abc() {
    	class B { //지역 이너 클래스
        }
        B b = new B(); //지역 이너 클래스 객체 생성
    }
}
package InnerClass;

class A {
	int a = 3; //필드 
	void abc() {
		int b = 5; //지역 변수 
		//지역 이너 클래스 
		class B{
			void bcd() {
				System.out.println(a);
				System.out.println(b);
				a = 5;
				//b = 7; 지역 이너 클래스에서 사용하는 지역 변수는 자동 final 선언
			}
		}
		B bb = new B();
		bb.bcd();
	}
}

public class InnerClass {
	public static void main(String[] args) {
		//객체 생성 및 메서드 호출
		A a = new A();
		a.abc();
	}
}

 

 - 지역 이너 클래스의 컴파일 이후 생성되는 클래스 파일 

package InnerClass;

class A { // A.class
	void abc() {
		class B {} //A$1B.class
		class C {} //A$1C.class
	}
	void bcd() {
		class C {} //A$2C.class
		class D {} //A$1D.class
	}
}

public class InnerClass {
	public static void main(String[] args) {
		
	}
}

 

'Java' 카테고리의 다른 글

13 - 3 장 이너 인터페이스  (0) 2023.06.05
13 - 2 장 익명 이너 클래스  (0) 2023.06.05
12 - 2장 인터페이스  (0) 2023.06.04
12-1장 추상 클래스  (0) 2023.06.02
11-2장 abstract 제어자  (0) 2023.06.02