티스토리 뷰
반응형
중첩 클래스 (nested class)
- 중첩 클래스는 다른 클래스 안에 정의된 클래스를 말한다.
- 자신을 감싼 바깥 클래스에서만 쓰여야함
- 정적 멤버 클래스, (비정적) 멤버 클래스, 익명 클래스, 지역 클래스
정적 멤버 클래스
- 다른 클래스 내부에서 static으로 선언된 클래스
- 다른 정적 멤버와 똑같은 규칙 적용
- 흔히 바깥 클래스와 함께 쓰일때만 유용한 public 도우미 클래스로 사용
public class Calculator {
public enum Operation { // 열거 타입도 암시적 static 이다.
PLUS, MINUS, MULTIPLE, SUBTRACT
}
}
비정적 멤버 클래스
- 다른 클래스 내부에서 static 없이 선언된 클래스
- 비정적 멤버 클래스 인스턴스는 바깥 클래스 인스턴스와 암묵적으로 연결 → 클래스명.this 로 바깥 인스턴스의 메서드를 호출하거나 참조를 가져올 수 있음
- 비정적 멤버 클래스는 바깥 인스턴스 없이는 생성할 수 없기 떄문에 개념상 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 있을수있다면(접근할 일이 없다면) 정적 멤버 클래스로 만들어야함
private 정적 멤버 클래스는 바깥 클래스가 표현하는 객체의 구성요소일때 사용함 ex) Map 구현체에는 Entry 객체들을 가지고 있는데, 모든 엔트리의 메서드들은 맵을 직접 사용하지는 않기 때문에 private 정적 멤버 클래스가 적절하다. - 어댑터 정의 시 자주 쓰임 : 어떤 클래스 인스턴스를 감싸서 마치 다른 클래스의 인스턴스처럼 보이게 하는 뷰로 사용
//컬렉션 인터페이스 구현들이 자신의 반복자를 구현할때 비정적 멤버 클래스 사용
public class MySet<E> extends AbstractSet<E> {
//생략
@Override
public Iterator<E> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<E> {
//생략
}
}
익명 클래스
- 이름없는 클래스로, 바깥 클래스의 멤버가 아니며 쓰이는 시점에 선언과 동시에 인스턴스가 만들어진다.
- 상수 변수 외 정적 멤버는 가질 수 없다. (final 기본타입과 문자열 필드만 가능)
- 인터페이스 구현이나 클래스 상속이 불가능
- 익명클래스가 상위 타입에서 상속한 멤버 외에는 호출 불가능
- 자바8 람다 이후부터는 익명클래스보다는 람다를 주로 사용
//익명 클래스
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
//자바8 이후 람다로 변경
Collections.sort(list, (o1, o2) -> Integer.compare(o1, o2));
지역 클래스
- 네가지 중첩 클래스 중 가장 드물게 사용됨
- 지역 변수를 선언할 수 있는 곳이면 선언 가능, 유효범위도 지역변수와 같음
- 익명 클래스처럼 비정적 문맥에서 사용될때만 바깥 인스턴스 참조 가능
- 정적 멤버는 가질 수 없음
결론
중첩 클래스는 정적 멤버 클래스, 비정적 멤버 클래스, 익명 클래스, 지역 클래스가 있다.
메서드 밖에서도 사용하거나 메서드 안에 정의하기엔 너무 길다면 멤버 클래스로 만든다.
멤버 클래스 인스턴스가 바깥 인스턴스를 참조한다면? 비정적, 아니면 정적으로 만들자.
중첩 클래스가 한 메서드 안에서만 쓰이고 해당 타입으로 쓰기에 적절한 클래스나 인터페이스가 이미 있다면
익명 클래스로 만들고 아니면 지역 클래스로 만들자.
반응형
'Java > Effective Java' 카테고리의 다른 글
[Effective Java] 26.로 타입은 사용하지 말라 (0) | 2022.03.18 |
---|---|
[Effective Java] 25.톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2022.03.17 |
[Effective Java] 23.태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2022.03.17 |
[Effective Java] 22.인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2022.03.17 |
[Effective Java] 21.인터페이스는 구현하는 쪽을 생각해 설계하라 (0) | 2022.03.16 |
댓글