도서/자바의 신

[도서/자바의 신] #16 클래스 안에 클래스가 들어갈 수도 있구나

yulee_to 2022. 12. 25. 05:33

자바의 신

✔️이 글은 [자바의 신 - 이상민 지음] 도서를 바탕으로 정리한 글입니다. 


클래스 안의 클래스

코드를 간단하게 하기 위해 클래스 안에 클래스가 들어가 있는 클래스를 Nested 클래스라고 한다.

Nested 클래스는 자바 기반의 UI 처리를 할때 사용자의 입력이나 , 외부의 이벤트에 대한 처리를 하는 곳에서 가장 많이 사용된다.

 

Nested 클래스는 선언 방법에 따라 두가지로 나뉜다.

  • Static nested 클래스 : static이 붙은 nested 클래스
  • 내부(inner) 클래스 : static이 안붙은 nested 클래스
    • 로컬 내부 클래스(local inner class) : 이름이 있는 내부 클래스
    • 익명 내부 클래스(anonymous inner class) : 이름이 없는 내부 클래스
    • 간단하게 줄여 로컬 클래스, 익명 클래스라고 부름 

Nested 클래스를 사용하는 이유

  • 한 곳에서만 사용되는 클래스를 논리적으로 묶어서 처리할 필요가 있을 때
  • 캡슐화가 필요할 때, 내부 구현을 감추고 싶을 때 ( A클래스의 private 변수를 접근하는 B 클래스를 외부에 노출시키고 싶지 않을 때)
  • 소스의 가독성과 유지보수성을 높이고 싶을 때

Static nested 클래스의 특징

내부 클래스는 감싸고 있는 외부 클래스의 어떤 변수도 접근이 가능하다.

반면에 Static nested 클래스는 외부 클래스를 컴파일하면 자동으로 컴파일되고 외부 클래스 이름 뒤에 $기호를 붙인 후 Nested 클래스의 이름과 .class인 클래스 파일이 만들어진다.

 

Static nested 클래스 객체를 생성할 때 외부 클래스 이름 뒤에 점을 찍고 nested 클래스 파일 이름을 써주면된다. 

Static nested 클래스는 클래스를 묶기 위해 쓰이는데 대학에서의 Student와 고등학교에서의 Student를 Static nested 클래스로 만들어주면 구별하기 쉬워진다.

내부 클래스와 익명 클래스

내부 클래스에는 static 선언부가 없고, 객체를 생성할 때는 외부 클래스 객체를 만들고 그 객체를 통해서 내부 클래스의 객체를 만들 수 있다.

내부 클래스는 하나의 클래스에서 어떤 공통적인 작업을 수행하는 클래스가 필요한데 다른 클래스에선 필요 없을 때 즉, 캡슐화를 위해 사용된다. 주로 GUI 관련 프로그램 개발시 리스너(Listener) 처리할 때 많이 사용된다.

 

로컬 클래스는 그냥 클래스 내부에 클래스를 선언해주면 되고, 익명 클래스의 경우엔 두 가지 방식으로 나뉜다.

익명 클래스를 넘겨줄 메소드이름 다음에 소괄호를 열어 준 뒤 new 클래스이름()을 해주고 바로 중괄호를 열어 그 안에 메소드들을 구현한 뒤 중괄호를 닫고 소괄호를 닫고 세미콜론을 해줘야 한다. 

이렇게 사용하면 클래스 이름도 없고, 객체 이름도 없어 다른 클래스나 메소드에서 참조할 수 없다.

객체를 해당 클래스 내에서 재사용하려면 객체를 생성하고 바로 중괄호를 열어 안에 메소드들을 구현해주고 중괄호를 닫은 후 세미콜론을 써주면 된다.

button.setListner(new EventListener() {
    public void onClick() {
        System.out.println("Maing Button Clicked"):
    }
});
// OR
EventListener listener = new EventListener() {
    public void onClick() {
        ...
    }
};

익명 클래스와 내부 클래스는 모두 다른 클래스에서 재사용할 일이 없을 때 만들어야 한다.

Nested 클래스의 특징은 꼭 알아야 한다

Static Nested 클래스에서는 외부 클래스의 static 변수만 참조할 수 있다.

내부 클래스와 익명 클래스는 외부 클래스의 어떤 변수도 참조 가능하다.

반대로 외부 클래스에서 Static Nested 클래스의 인스턴스 변수나 내부 클래스의 인스턴스 변수의 참조도 가능하다.


정리해 봅시다

1. Nested 클래스에 속하는 3가지 클래스는?

Static Nested class, Local inner class, Anonymous inner class

2. Nested 클래스를 컴파일하면 Nested 클래스 파일의 이름은 어떻게 되나요?

감싼클래스$Nested클래스.class가 된다.

3. Static Nested 클래스는 다른 Nested 클래스와 어떤 차이가 있나요?

객체를 생성하는 방법이 다르다.

4. Static Nested 클래스의 객체 생성은 어떻게 하나요?

감싼클래스.StaticNested클래스 객체이름 = new 감싼클래스.StaticNested클래스();

5. 일반적인 내부 클래스의 객체 생성은 어떻게 하나요?

감싼클래스.내부클래스 객체이름 = 감싼클래스객체.new 내부클래스();

6. Nested 클래스를 만드는 이유는 무엇인가요?

한 곳에서만 사용되는 클래스를 논리적으로 묶어서 처리할 때, 캡슐화가 필요할 때, 소스의 가독성과 유지보수성을 높이고 싶을 때 사용한다.

7. Nested 클래스에서 감싸고 있는 클래스의 private로 선언된 변수에 접근할 수 있나요?

YES

8. 감싸고 있는 클래스에서 Nested 클래스에 선언된 private로 선언된 변수에 접근할 수 있나요?

YES

728x90