본문 바로가기
Language/JAVA

[JAVA]내부클래스

by 바까 2020. 7. 1.
반응형

내부클래스:

 

클래스 내부에 선언한 클래스로

클래스 내부에서만 사용할 목적으로 만드는 클래스이다.

//문법
class Out{ //외부클래스
	class In{ //내부클래스
    }
}

내부클래스의 종류

 

[변수 측면에서]

class ABC{
	
    int n1;			//인스턴스 변수
    static int n2; 	//정적변수
	
    public void abc(){
    	int n3; 	//지역변수
    }

}

 

[클래스 측면에서]

class ABC{//외부클래스

	class In{//인스턴스 내부클래스 - static이 붙지않음
    
    	static class SIn{//정적 내부 클래스 - static이 붙음
        	
        }
    }
    
    public void abc(){//메소드 안에도 클래스가 들어갈 수 있다.
    
    	class Local{//지역 내부 클래스
        }
    }
}

//최상위만 외부, 나머진 모두 내부


인스턴스 내부 클래스 (instance inner class)

 

- 외부 클래스를 생성한 후 생성

- 정적 변수, 정적 메서드는 사용할 수 없다.

- 외부 클래스의 참조 변수를 이용하여 내부 클래스를 사용한다.

- 내부 클래스가 private이 아니면 다른 외부 클래스에서도 생성가능하다.

- 클래스 내부에서만 사용할 목적이라면 private로 선언한다.

 

[실습] 인스턴스 내부 클래스 실행하기

//외부 클래스 정의
class OutClass{
	//필드 정의
	private int num = 10;			//외부 클래스 인스턴스 변수
	private static int sNum = 20;	//외부 클래스 정적 변수
	
	//내부 클래스 자료형 변수를 먼저 선언
	private InClass inClass;
	
	//외부클래스의 디폴트 생성자 정의
	//외부 클래스가 생성된 후에 내부 클래스 생성가능
	public OutClass() {
		inClass = new InClass();
	}
	//인스턴스 내부 클래스 정의
	class InClass{
		
		int inNum = 100;	//내부 클래스의 인스턴스 변수
		
		//인스턴스 내부 클래스에 정적 변수 선언은 불가능->오류발생
		//static int SInNum = 200; 
		
		//메서드 정의
		void inTest() {
			System.out.println(num);	//외부 클래스의 인스턴스 변수
			System.out.println(sNum); 	//외부 클래스의 정적 변수 
		}
		
		//인스턴스 내부 클래스에서 정적 메소드 정의 불가능 ->오류 발생
		//static void sTest() {}
	}
	//다른 메서드를 선언하는 메서드 정의
	public void usingClass() {
		inClass.inTest();
	}
	
}
public class InnerClassTest {
	
	public static void main(String[] args) {
		
		//OutClass 객체 선언
		OutClass outClass = new OutClass();
		
		//내부 클래스의 메소드 호출
		outClass.usingClass();//20 10출력
	}
	
}

정적 내부 클래스(static inner class)

 

- 외부 클래스의 생성과 무관하게 사용가능

- 정적 변수, 정적 메서드 사용가능

 

[정적 내부 클래스의 메서드에서 변수 사용 여부]

정적 내부 클래스의 메서드 변수의 유형 사용가능 여부
일반 메서드
void inTest()
외부 클래스의 인스턴스 변수(num) X
외부 클래스의 정적 변수(sNum) O
정적 내부 클래스의 인스턴스 변수(inNum) O
정적 내부 클래스의 정적 변수(sInNum) O
정적 메서드
static void sTest()
외부 클래스의 인스턴스 변수(num) X
외부 클래스의 정적 변수(sNum) O
정적 내부 클래스의 인스턴스 변수(inNum) X
정적 내부 클래스의 정적 변수(inNum) O

 

[실습] 정적 내부 클래스 실행

//외부클래스
class OutClass{
	
	//필드정의
	private int num = 10;			//외부 클래스 인스턴스 변수
	private static int sNum = 20;	//외부 클래스 정적 변수
	
	//정적 내부 클래스를 정의
	static class InStaticClass{
		
		int inNum = 100; 			//정적 내부 클래스의 인스턴스 변수
		static int sInNum = 200; 	//정적 내부 클래스의 정적 변수
		
		//정적 내부 클래스의 일반 메서드 정의
		void inTest() {
			//System.out.println(num);	//외부 클래스 인스턴스 변수
			System.out.println(sNum);	//외부 클래스 정적 변수
			System.out.println(inNum);	//정적 내부 클래스의 인스턴스 변수
			System.out.println(sInNum);	//정적 내부 클래스의 정적 변수
		}
		//정적 내부 클래스의 정적 메서드 정의
		static void sTest() {
			//System.out.println(num);	//외부 클래스 인스턴스 변수
			System.out.println(sNum);	//외부 클래스 정적 변수
			//System.out.println(inNum);//정적 내부 클래스의 인스턴스 변수
			System.out.println(sInNum);	//정적 내부 클래스의 정적 변수
		}
	}
}

public class StaticInnerClassTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//외부 클래스 객체를 생성하지 않고 바로 정적 내부 클래스 객체 생성이 가능.
		OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
		
		sInClass.inTest();//일반메서드
		System.out.println("===============");
		OutClass.InStaticClass.sTest();//정적메서드
	}

}


지역 내부 클래스(Local Inner Class)

 

- 지역 변수와 같이 메서드 내부에서 정의하여 사용하는 클래스

- 메서드의 호출이 끝나면 메서드의 사용된 지역 변수의 유효성은 사라진다.

- 메서드 호출 이후에서 사용해야 하는 경우가 있으므로 지역 내부 클래스에서 사용하는 메서드의 지역변수나 매개 변수는 final로 선언

 

[실습] 지역 내부 클래스 실행

//외부클래스
class OutClass{
	
	//필드 선언 및 초기화
	int outNum = 100;		//외부클래스 인스턴스 변수
	static int sNum = 200;	//외부클래스 정적 변수
	
	//Runnable 인터페이스를 구현하기 위한 메서드 정의
	Runnable getRunnable(int i) {
		
		int num = 100; //지역변수
		
		//지역 내부 클래스를 정의
		class MyRunnable implements Runnable{
			
			int localNum = 10; //지역 내부 클래스의 인스턴스 변수
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//num = 200;//final을 쓰진 않았지만 final을 쓴 것과 같은효과
				//i=100; //매개변수도 지역변수이기 때문에 같은 오류 발생
				System.out.println(i);
				System.out.println(num);		//지역변수
				System.out.println(localNum);	//지역 내부 클래스의 인스턴스 변수
				System.out.println(outNum);		//외부클래스 인스턴스 변수
				System.out.println(sNum);		//외부클래스 정적 변수
				
			}
			
		}
		return new MyRunnable();
	}
}

public class LocalInnerClassTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		//객체생성
		OutClass outClass = new OutClass();
		
		//메서드를 호출하여 결과값을 runner에 대입
		Runnable runner = outClass.getRunnable(10);
		
		runner.run();
	}

}

 


익명 내부 클래스(Anonymous Inner Class)

이름이 없는 클래스

주로 하나의 인터페이스나 하나의 추상 클래스를 구현하는데 더 사용

인터페이스나 추상 클래스 자료형의 변수에 직접 대입하여 생성하거나 지역 내부 클래스의 메서드 내부에서 생성하여 반환 할 수 있다.

*참고- 안드로이드의 widget의 이벤트 핸들러를 구현할 때 많이 사용

[실습]익명 내부 클래스 실행

//외부클래스
class OutClass{
	
	//메소드 정의
	Runnable getRunnable(int i) {
		int num = 100; //지역변수
		
		
		//MyRunnable 클래스 이름을 빼고 클래스를 바로 생성
		return new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println(i);//출력은 되나 변경은 불가능
				System.out.println(num);//출력은 되나 변경은 불가능
			}}; //클래스 끝에 세미콜론(;)을 넣어준다
	}
	
	//익명 내부 클래스를 변수에 대입 가능
	Runnable runner =new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			System.out.println("익명 클래스");
		}
		
	};
}

public class AnonymousInnerClassTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		OutClass outClass = new OutClass();
		
		//메서드를 호출하여 결과값을 runner에 대입.
		Runnable runner = outClass.getRunnable(10);
		//메서드 호출
		runner.run();
		outClass.runner.run();
	}

}


[정리]

  인스턴스 내부 클래스 정적 내부 클래스 지역 내부 클래스 익명 내부 클래스
구현위치 외부 클래스 멤버 변수와 동일 외부 클래스 멤버 변수와 동일 메서드 내부에 구현 메서드 내부에 구현
변수에 대입하여 직접 구현
사용할 수 있는 외부 클래스 변수 외부 인스턴스 변수, 외부 전역변수 외부 전역변수 외부 인스턴스 변수, 외부 전역변수 외부 인스턴스 변수, 외부 전역 변수
생성방법 외부 클래스를 먼저 만든 후 내부 클래스 생성 외부 클래스와 무관하게 생성 메서드 호출할 때 생성 메서드를 호출할 때 생성되거나, 인터페이스 타입변수에 대입할 때 new 예약어를 사용하여 생성

 

반응형

'Language > JAVA' 카테고리의 다른 글

[JAVA]Class 클래스  (0) 2020.07.01
[JAVA] 람다식(lambda expression)  (0) 2020.07.01
[JAVA]StringBuffer VS StirngBuilder  (0) 2020.07.01
[JAVA]String 클래스  (0) 2020.07.01
[JAVA]Object 클래스  (0) 2020.07.01

댓글