![](https://velog.velcdn.com/images/yeomyaloo/post/32a55765-b6b5-43eb-a9c5-32cb2d4ac772/image.png)
4장 클래스와 인터페이스
[24. 멤버 클래스는 되도록 static으로 만들라]
- 중첩 클래스의 4가지 종류에 대해서 알아보고 해당 종류의 클래스들이 어떨때 사용되는지 알아보자
[핵심 정리]
- 중첩 클래스는 네 가지가 있으며 각각의 쓰임이다르다.
- 메서드 밖에서도 사용해야 하는 경우나 메서드 안에 정의하기 너무 길다면 멤버 클래스로 만든다
- 멤버 클래스의 인스터스 각각이 바깥 인스턴스를 참조하는 경우엔 비정적으로, 그렇지 않으면 정적으로 만들자
- 중첩 클래스가 한 메서드 안에서만 쓰이면서 그 인스턴스를 생성하는 지점이 단 한 곳이고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있는 경우엔 익명 클래스로 만들고 그렇지 않으면 지역 클래스로 만든다.
[중첩 클래스란?]
1. 의의와 코드
public class TopLevelClass{
class InnerLevelClass{
}
}
public class TopLevelClassStatic{
public static class StaticInnerLevelClass{
}
}
2. 정적 중첩 클래스 사용 방식과 내부 클래스 & 중첩 클래스 사용 방식 차이점
2-1. 정적 중첩 클래스 사용 방식
public static void main(String[] arg){
StaticInnerLevelClass nestedObj = new TopLevelClassSatic.StaticInnerLevelClass();
}
- 따로 생성자를 이용해서 객체를 생성하지 않아도 된다.
- 이때 그저 해당 클래스에 접근하기만 하면 된다.
- 위의 작업만 해도 정적 중첩 클래스 내부에 정의해둔 메서드에 접근할 수 있다.
2-2. 내부 클래스 & 중첩 클래스 사용 방식
public static void main(String[] arg){
TopLevelClass topLevelClass = new TopLevelClass();
InnerLevelClass innerNestedClass =
topLevelClass.new InnerLevelClass();
}
- 위의 정적 중첩 클래스와 달리 탑 클래스를 객체 생성한 후에 다시 비정적 중첩 클래스를 생성해주어야 한다.
- 위의 작업을 진행해야 해당 비정적 중첩 클래스 내부에서 정의한 메서드를 사용할 수 있다.
3. 중첩 클래스의 종류
- 중첩 클래스는 말 그대로 바깥 클래스 안에 다시 클래스를 정의한 것을 의미한다.
- 이때 static을 달았으면 static nested class고 나머지는 inner class에 해당한다.
- 이때 inner class의 경우엔 또 다시 안에서 사용되는 방법에 따라서 종류가 세가지로 나뉜다.
![](https://velog.velcdn.com/images/yeomyaloo/post/aeb26ca4-b893-4f35-ad59-662f6a56f96e/image.png)
3-1. 정적 멤버 클래스
- 클래스 안에 선언되고 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고는 일반 클래스와 동일하다.
-private로 정적 중첩 클래스를 선언하면 바깥 클래스에서만 접근할 수 있다.
- 주로 바깥 클래스와 함께 사용할 때 유용한 public 도우미 클래스로 쓰인다.
3-2. 비정적 멤버 클래스
- static이 붙지 않은 중첩 클래스로 의미상의 차이는 정적 멤버 클래스와 크게 다르다.
- 해당 비정적 멤버 클래스의 경우엔 바깥 클래스의 인스턴스와 암묵적으로 연결되어 있다.
- 바깥 인스턴스의 메서드를 호출하거나 바깥 인스턴스의 참조를 가져올 수 있다.
- 비정적 멤버 클래스의 경우엔 바깥 클래스의 인스턴스 없이는 생성할 수 없다.
- inner class가 이에 해당한다. (해당 작업이 바깥 인스턴스와 연결되어 있고, 바깥 인스턴스 참조 없이는 해당 중첩 클래스 생성도 클래스 내의 메서드 접근도 불가하기 때문이다.)
- 보통은 생성자 없이도 만들어지지만
바깥_인스턴스.new non-static_nested_class(args)
으로 수동 생성하기도 한다.
- 해당 클래스는 바깥 클래스 내부에 생성되어 메모리를 차지하고 생성 시간도 더 걸린다.
- 바깥 인스턴스에서 접근할 일이 있을 때만 사용되는 비정적 내부 클래스이기 때문에 바깥에서 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적 멤버 클래스로 만들자.
3-3. 익명 클래스
- 이름이 없는 클래스가 익명 클래스이다.
- 해당 클래스는 바깥 클래스의 멤버가 아니다. 이는 멤버와 달리 쓰는 시점에 선언과 동시에 인스턴스가 만들어지기 때문이다.
- 멤버라면 인스턴스가 만들어지는 시점은 해당 인스턴스를 생성하는 시점이기 때문이다. (말이 이상하지만 대부분의 클래스 내부의 멤버들은 클래스에서 객체 생성 시점이기 때문에 사용시점인 익명 클래스와는 생성 시점이 다르다)
3-4. 지역 클래스
- 가장 드물게 사용한다.
- 지역 클래스느 지역변수를 선언할 수 있는 곳이라면 어디든 선언 가능하다.
- 지역 변수처럼 사용한다.
[static 중첩 클래스를 사용하자]
- 정적 중첩 클래스를 사용해야 하는 경우?
: 메서드 밖에서도 사용해야하고 메서드 안에서 정의하기에 너무 긴 경우라면 멤버 클래스로 만들자
- 비정적 중첩 클래스를 사용해야 하는 경우?
: 인스턴스 각각이 바깥 인스턴스를 참조하는 경우엔 비정적 중첩 클래스를 사용하자
- 익명 클래스를 사용해야 하는 경우?
: 중첩 클래스가 한 메서드 안에서 사용되고 그 인스턴스를 생성하는 지점이 한곳이면서 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있는 경우라면 익명 클래스를 사용하자
- 그렇지 않으면 지역 클래스로 만들어 사용하자