JAVA Spring

0. JAVA 기초 (7)

Louis.T.Kim 2020. 3. 7. 22:31

- 내부 클래스(Inner Class) : 클래스 안에 클래스

 

- 컴파일 시, Class가 총 3개 생성된다. OutClass$InClass가 추가로 생성된다.

 

- Instance/Static Inner Class

package innerClass;

class OutClass {
	
	private int num = 10;
	private static int sNum = 20;
	private InClass inClass;
	
	
	public OutClass() {
		inClass = new InClass();
	}
	// Instance Inner Class
	
	// 단, static 변수를 쓰고 싶으면 Static Inner Class를 만들어야한다.
	// InnerClass의 Instance 생성 없이 쓸 수 있어야하기 때문이다.
	
	class InClass { 
		int iNum = 100;
		
		void inTest() {
			System.out.println(num);
			System.out.println(sNum);
		}
	}
	
	public void usingInner() { // innerClass를 사용하기 위해 public 함수를 쓴다. 
		inClass.inTest();
	}
	
	
	// Static Inner Class
	
	//static Inner Class 내에서는 static VAR/METHOD 생성이 가능  
	static class InStaticClass {
		int inNum = 100;
		static int sInNum = 200;
		
		void inTest() {
			System.out.println(inNum);
			System.out.println(sInNum);
			System.out.println(sNum);
		}
		static void sTest() {
			//System.out.println(inNum); // ERROR!!! static이므로 instance VAR 사용 불가. 
			System.out.println(sInNum);
			System.out.println(sNum);
			
		}
	}
	
	
	
}

public class InnerTest {
	public static void main(String[] args) {
		OutClass outClass = new OutClass();
		outClass.usingInner(); // innerClass를 사용하기 위해 public 함수를 쓴다.
		
		// Inner Class의 직접 접
		// OutClass instance를 생성한 후에 그것의 InClass로 할당해줘야 한다. 
		OutClass.InClass myInClass = outClass.new InClass(); 
		
		
		// Static Class 내의 METHOD 직접 접근 
		OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
		sInClass.inTest();
		
		// Static Class 내의 static METHOD 직접 접근
		OutClass.InStaticClass.sTest();
		
		
	}

}

 

 

- Local Inner Class

package innerClass;

class Outer {
	
	int outNum = 100;
	static int sNum = 200;
	
	Runnable getRunnable(int i) { // Runnable METHOD
		
		int num = 100;
		// 지역 내부 Class : 함수 안에 만들어진 Class 
		class MyRunnable implements Runnable {
			
			@Override
			public void run() {
				
				// 아래 num, i 등의 지역 변수들은 getRunnable()이 끝나면 사라진다.
				// 그러나 MyRunnable Class 안에서 이 변수들이 존재하면,
				// MyRunnable Class 만 따로 호출되었을 때 문제가 생긴다. 
				// 따라서, num, i는 컴파일러가 자동적으로 final을 붙여 상수로 만들어준다.
				// 따라서 지역 변수는 inner Class에서 변경이 불가하다. 
				
				// num += 10; 
				// i = 200;
				System.out.println(i);
				System.out.println(num);
				System.out.println(outNum);
				System.out.println(Outer.sNum);
				
			}
		}
		return new MyRunnable(); // inner Class를 반환 
	}
}


public class LocalInnerClassTest {

	public static void main(String[] args) {
		Outer outer = new Outer();
		Runnable runnable = outer.getRunnable(50);
		
		runnable.run();

	}

}

 

- Anonymous Inner Class

 

package innerClass;



package innerClass;

class Outer {
	
	int outNum = 100;
	static int sNum = 200;
	
	Runnable getRunnable(int i) { // Runnable METHOD
		
		int num = 100;
		
        // 위의 Local Inner Class에서 어차피 MyRunnable Class는 한 번만 쓰일 것이므로
        // 아래처럼 바로 return한다. 
        
		return new Runnable() { // Anonymous Inner Class 
			
			@Override
			public void run() {

				System.out.println(i);
				System.out.println(num);
				System.out.println(outNum);
				System.out.println(Outer.sNum);
				
			}
		};
	}
	
	Runnable runner = new Runnable() { // 이렇게도 사용 가능 (1/2) 
		
		@Override
		public void run() {
			System.out.println("test");
		}
	};
	
}


public class AnnoymousInnerClassTest {

	public static void main(String[] args) {
		Outer outer = new Outer();
		Runnable runnable = outer.getRunnable(50);
		
		runnable.run();
        
        outer.runner.run(); // 이렇게도 사용 가능 (2/2) 

	}

}