[Java] 7. 객체지향 프로그래밍 2 #8 내부 클래스(Inner Class)

2022. 5. 23. 17:28JAVA/Language

1. 내부 클래스란 무엇인가?

내부 클래스란 클래스 안에 선언된 클래스

 

내부 클래스를 정의하는 이유는 무엇인가?

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

 

내부 클래스의 장점

  • 내부 클래스에서 외부 클래스의 멤버(필드멤버, 메서드)들을 쉽게 접근할 수 있음
  • 외부에 내부 클래스 자체를 감추어 코드의 복잡성을 줄일 수 있음 (캡슐화)
// before
class A{
	...
}

class B{
	...
}

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

 

2. 내부 클래스의 종류와 특징

내부 클래스 종류와 특징

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

 

3. 내부 클래스의 선언

class Outer{
	class InstanceInner{ // 인스턴스 클래스
    }
    
    static class StaticInner{ // 정적 클래스
    }
    
    void myMethod(){
    	class LocalInner{	// 지역 클래스
        }
    }
}

 

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

외부 클래스에 선언된 인스턴스 클래스(instance class)와 정적 클래스(static class)는 외부 클래스의 멤버 변수와 같은 성질을 갖습니다. 여기서 멤버 변수와 같은 성질은 다음과 같습니다.

  • 클래스안에 선언된 정적 멤버(필드멤버, 메서드)는 객체 생성 없이 인스턴스 멤버를 참조할 수 없음

위 설명에 대한 예제는 다음과 같습니다.

public class Person {
	String name;
	static final String KIND = "human"; // 정적(클래스) 멤버
	
	static void method() {
		// name 인스턴스 멤버는 아직 객체생성을 하지 않았기 때문에 정적 멤버(method)는
		// name을 참조할 수 없음, 컴파일 에러
//		System.out.println(name);
		// KIND 정적 멤버는 클래스 초기화시 할당됬기 때문에 참조가 가능함
		System.out.println(KIND);
	}
	
	void sayName() {
		// 인스턴스 멤버인 sayName은 같은 인스턴스 멤버인 name 필드멤버를 참조가 가능함
		System.out.println(name);
		// 인스턴스 멤버인 sayName은 모든 객체가 공유하는 멤버인 정적 멤버를 참조가 가능함
		System.out.println(KIND);
	}	
}

위 예제와 같이 클래스안에 선언된 멤버에는 필드멤버(name, KIND)가 있고 메서드에는 method, sayName 메서드가 있습니다. 그리고 static 제어자가 붙어있다면 정적 멤버이고 없다면 인스턴스 멤버여서 객체를 생성한다음 참조가 가능합니다. 이와같이 필드 멤버 또는 메서드와 마찬가지로 클래스 조차도 static이 붙었냐 안붙었냐에 따라서도 필드멤버와 메서드와 같은 성질을 갖습니다.

 

5. 익명 클래스(anonymous class)

익명 클래스의 형식

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

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

 

익명 클래스의 특징

  • 익명 클래스는 이름이 없기 때문에 생성자를 가질 수 없음
  • 조상 클래스의 이름이나 구현하고자 하는 인터페이스의 이름을 사용해서 정의함
  • 오직 단 하나의 클래스를 상속받거나 단 하나의 인터페이스만을 구현할 수 있음

 

익명 클래스의 예제

public class InnerEx6{
	Object iv = new Object() { // 익명 클래스
		void method() {
			System.out.println("call anonymous class method1");
		}
	};
	
	static Object cv = new Object() { // 익명 클래스
		void method() {
			System.out.println("call anonymous class method2");
		}
	};
	
	void myMethod() {
		Object lv = new Object() {	// 익명 클래스
			void method() {
				System.out.println("call nonymous class method3");
			}
		};
		
	}
}

위 예제를 보면 Object 클래스를 상속하면서 익명 클래스를 정의한 것을 볼 수 있습니다.

 

References

[도서] Java의 정석, 남궁 성 지음
[Java] inner class 와 inner static class 차이