Notice
Recent Posts
Recent Comments
Link
Tags
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

JongDDA의 한걸음 한걸음씩

[Java] 내부 클래스(Inner class) 본문

개발/Java

[Java] 내부 클래스(Inner class)

종따 2021. 8. 20. 21:59
728x90

내부 클래스(Inner class)

내부 클래스는 클래스 내에 선언된 클래스이다. 한 클래스를 다른 클래스의 내부 클래스로 선언하면 두 클래스의 멤버들 간에 서로 쉽게 접근할 수 있다는 장점과 외부에는 불필요한 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다는 장점을 얻을 수 있다.

내부 클래스 장점
- 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
- 코드의 복잡성을 줄일 수 있다. (캡슐화)

 

구조

class A{ // 외부 클래스
	...
    class B{ // 내부 클래스
    	...
    }
    ...
}

위 코드는 외부 클래스(outer class) A가 내부 클래스(Inner class) B를 감싸고 있는 구조이다.

 

내부 클래스의 종류와 특징

내부 클래스의 종류는 변수의 선언위치에 따른 종류와 같다. 내부 클래스는 마치 변수를 선언하는 것과 같은 위치에 선언할 수 있으며, 변수의 선언위치에 따라 인스턴스 변수, 클래스 변수(static 변수), 지역변수로 구분되는 것과 같이 내부 클래스도 선언위치에 따라 다음과 같이 구분되어 진다. 

 

내부 클래스 특징
인스턴스 클래스(instance class) 외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 인스턴스멤버 처럼 다루어진다. 주로 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언된다.
스태틱 클래스(static class) 외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 static멤버처럼 다루어 진다. 주로 외부 클래스의 static 멤버, 특히 static 메서드에서 사용될 목적으로 선언된다.
지역 클래스(local class) 외부 클래스의 메서드나 초기화블럭 안에 선언하며, 선언된 영역 내부에서만 사용될 수 있다.
익명 클래스(anonymous class) 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용)

 

내부 클래스의 선언

 

아래의 코드를 보자. 

class Outer1{
	int iv = 0;
    static int cv = 0;
    
    void Method(){
    	int lv = 0;
    }
}

class Outer2{
	class IntanceInner {}
    static class StaticInner {}
    
    void Method(){
    	class LocalInner {}
    }
}

Outer2 클래스에는 3개의 서로 다른 종류의 내부 클래스가 선언되어 있다. 두 클래스를 비교해 보면 내부 클래스의 선언위치가 변수의 선언위치와 동일함을 알 수 있다.

변수가 선언된 위치에 따라 인스턴스 변수, 클래스 변수(static 변수), 지역변수로 나뉘듯이 내부 클래스도 이와 마찬가지로 선언된 위치에 따라 나뉜다. 그리고 각 내부 클래스의 선언 위치에 따라 같은 선언위치의 변수와 동일한 유효범위와 접근성을 갖는다.

 

내부 클래스의 제어자와 접근성

아래 코드에서 인스턴스클래스와 스태틱 클래스는 외부 클래스의 멤버변수와 같은 위치에 선언되며, 또한 멤버변수와 같은 성질을 갖는다. 따라서 내부 클래스가 외부 클래스의 멤버와 같이 간주되고, 인스턴스멤버와 static 멤버 간의 규칙이 내부 클래스에도 똑같이 적용된다.

 

class Outer1{
	private int iv = 0;
    protected static int cv = 0;
    
    void Method(){
    	int lv = 0;
    }
}

class Outer2{
	private class IntanceInner {}
    protected static class StaticInner {}
    
    void Method(){
    	class LocalInner {}
    }
}

내부 클래스도 클래스이기 때문에 abstract나 final 같은 제어자를 사용할 수 있을 뿐만 아니라, 멤버변수들처럼 private, protected과 접근제어자도 사용이 가능하다.

 

내부 클래스 예제

 

EX)

public class OuterClassEx1 {
	private int a = 10;
	static int b = 20;
	static final int c = 30;
	// member 변수와 같은 위치에 놓고 사용하는 member inner class
	class InnerClass {
		int d = 40;
		//static int e = 50; // static 클래스만 static 멤버를 가질 수 있다.
		static final int f = 30; // final과 static이 동시에 붙은 변수는 상수 이므로 정의 가능
		void print() {
			System.out.println(" a : " + a);
			System.out.println(" b : " + b);
			System.out.println(" c : " + c);
			System.out.println(" d : " + d);
			//System.out.println(" e : " + e);
			System.out.println(" f : " + f);
		}
	} 
	public static void main(String[] args) {
		System.out.println(OuterClassEx1.b);
		
		OuterClassEx1 oc1 = new OuterClassEx1();
		System.out.println(oc1.a); // private 접근 가능
		System.out.println("--------------------------------");
		OuterClassEx1.InnerClass ic = oc1.new InnerClass();
		System.out.println(ic.d);
		ic.print();
	}
}

 

EX2)

 

import OuterClassEx1.InnerClass;

public class OuterClassEx2 {
	private int a = 10;
	static int b = 20;
	static final int c = 30;
	
	static class InnerClass2 {
		int d = 40;
		static int e = 50;
		static final int f = 30;
		void print() {
			//System.out.println(" a : " + a); // 스테틱 클래스는 외부 인스턴스멤버에 접근할 수 없다.
			System.out.println(" b : " + b);   // static 변수는 접근 가능
			System.out.println(" c : " + c);
			System.out.println(" d : " + d);
			System.out.println(" e : " + e);
			System.out.println(" f : " + f);
		} // print() end
	} 
	public static void main(String[] args) {
		
		System.out.println(OuterClassEx2.b);
		
		InnerClass2 ic2 = new InnerClass2();
		ic2.print();
	}
}

 

 

EX3)

package day13;



public class OuterClassEx3 {
	private int a = 10;
	static int b = 20;
	static final int c = 30;

	public void printAll() {
		// 클래스가 마치 지역변수 처럼 사용
		// Local inner class
		class LocalInnerClass {
			
			int d = 40;
			//static int e = 50;
			static final int f = 30;

			void print() {
				// System.out.println(" a : " + a);
				System.out.println(" b : " + b);
				System.out.println(" c : " + c);
				System.out.println(" d : " + d);
				//System.out.println(" e : " + e);
				System.out.println(" f : " + f);
			}
		}	
		LocalInnerClass ic = new LocalInnerClass();
		ic.print();
		// 지역변수 처럼 메서드가 종료되면 사라지는 클래스
	}
	public static void main(String[] args) {
		OuterClassEx3 oc3 = new OuterClassEx3();
		oc3.printAll();
	}
}

 

익명 클래스(anonymous class)

익명 클래스는 다른 내부 클래스들과는 달리 이름이 없다. 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스이다.

 

new 조상클래스이름() {
	// 멤버 선언
}

	    또는
    
new 구현인터페이스이름(){
	// 멤버 선언
}

이름이 없기 때문에 생성자도 가질 수 없으며 조상클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해서 정의하기 때문에 하나의 클래스로 상속받는 동시에 인터페이스를 구현하거나 둘 이상의 인터페이스를 구현할 수 없다. 오로지 단 하나의 클래스를 상속받거나 단 하나의 인터페이스만 구현할 수 있다.

 

EX)

class Ex{
	Object iv = new Object(){ void method(){} };  // 익명 클래스
    static Object cv = new Object(){ void method(){} ]; // 익명 클래스
    
    void myMethod(){
 		Object lv = new Object(){ void method(){} };  // 익명 클래스   
    }
}

 

 

 

 

 

 

 

 

 

 

728x90
반응형

'개발 > Java' 카테고리의 다른 글

[Java] 예외처리(exception handling)  (0) 2021.08.23
[Java] java.lang 패키지 & util classes  (0) 2021.08.21
[Java] 입출력(I/O)  (0) 2021.08.19
[Java] 인터페이스(Interface)  (0) 2021.08.18
[Java] 추상 클래스(abstract class)  (0) 2021.08.18
Comments