Nested 클래스
- 클래스 안에 클래스가 들어갈 수 있다.
- 클래스 안에 들어가는 클래스를 Nested 클래스라고 한다.
- 코드를 간단히 표현하기 위해 사용한다.
- UI 처리를 할 때 사용자의 입력이나 외부의 이벤트에 대한 처리를 하는 곳에서 가장 많이 사용된다.
- 선언 방식에 따라 Static nested 클래스 / 내부 클래스로 나뉜다.
- static으로 선언 시 Static nested 클래스
- static이 없으면 내부 클래스
- 내부 클래스
- 익명 클래스 (이름이 없는 클래스)
- 여러 클래스가 하나의 파일 안에 선언되어 있는 경우
- 파일 명은 public으로 선언된 클래스의 이름과 동일해야 한다.
- 동일하지 않거나 public 클래스가 여러 개인 경우 컴파일 에러가 발생한다.
- 감싸고 있는 클래스만 컴파일해도 자동으로 나머지 클래스들도 컴파일된다.
- 여러 개의 .class 파일이 만들어진다.
- ex) 감싸고 있는 public class가 Outer 클래스, Nested 클래스를 Inner 클래스로 가정
Outer.class 파일과 Outer$Inner.class 파일이 생성된다. - 감싸고 있는 클래스 이름 뒤에 $ 기호를 붙인 후 Nested 클래스의 이름이 붙는다.
- 파일 명은 public으로 선언된 클래스의 이름과 동일해야 한다.
- Nested class를 사용하는 이유
- 한 곳에서만 사용되는 클래스를 논리적으로 묶어 처리할 때 (Static Nested 클래스)
- 캡슐화가 필요할 때 = 내부 구현을 감추고 싶을 때 ( 내부 클래스 )
- 소스의 가독성과 유지보수성을 높이고 싶을 때
- 내부 클래스는 자신을 감싸고 있는 외부 클래스의 어떤 변수도 접근 가능하다.
- static nested 클래스의 경우 static으로 선언된 클래스이기 때문에 외부 클래스 변수 중 static 변수(클래스 변수)만 참조할 수 있다.
- 익명 클래스 / 내부 클래스는 어떤 변수라도 참조할 수 있다. (private, static 등등 모두 참조 가능)
- 외부 클래스에서 Nested 클래스의 어떤 변수에도 접근 가능하다.
Static Nested class
- Static nested 클래스는 겉으로 보기에는 유사하지만 내부적으로 구현이 달라야 할 때 사용한다.
- ex) 클래스 School, University가 있을 때 Student 클래스를 만들면 어느 클래스의 Student인지 모호해질 수 있는데 이런 경우 School 내부에 static nested 클래스인 Student를 만들어서 클래스의 용도를 명확하게 하며 School에서만 사용가능하고 University 클래스에서는 사용 불가능한 Student 클래스를 만들 수 있다.
- Static Nested 클래스 객체 생성
- 감싸고 있는 클래스명.static nested 클래스명 = new 감싸고 있는 클래스명.static nested 클래스 생성자();
- 객체 사용 방식은 일반 클래스와 동일하다.
// Outer가 외부 클래스, Inner가 Static nested 클래스라고 가정
Outer.Inner inner = new Outer.Inner();
inner.setValue();
내부 클래스 / 익명 클래스
내부 클래스 (local inner class)
- Static nested 클래스와 차이점으로는 클래스 선언 시 static의 유무의 차이다.
- 하나의 클래스에서 어떤 공통적인 작업을 수행하는 클래스가 필요한데 다른 클래스에서는 그 클래스가 전혀 필요없을 때(캡슐화) 내부 클래스를 만들어서 사용한다.
- GUI 관련 프로그램을 개발할 떄 가장 많이 사용한다.
- listener라는 것을 처리할 때 사용된다.
- 어떤 버튼이 눌렸을 때, 키보드 입력이 되었을 때 Event가 발생한다.
- 어떤 Event가 발생했을 때 해야 하는 작업을 정의하기 위해 내부 클래스를 작성해 사용한다.
- 하나의 애플리케이션에서 Event 발생 시 수행해야하는 작업이 대부분 다르기 때문에 하나의 별도 클래스보다 내부 클래스를 만드는 것이 훨씬 편하다.
- 내부 클래스보다 편한 방식은 익명 클래스를 만들어 사용하는 것이다.
- GUI 관련 프로그램을 개발할 떄 가장 많이 사용한다.
- Static nested 클래스와 객체 생성 방식이 다르다.
- 외부 클래스의 객체를 먼저 만들고 그 객체를 통해 내부 클래스의 객체를 만들 수 있다.
- 외부 클래스명 객체명 = new 외부 클래스 생성자();
외부클래스명.내부 클래스명 객체명 = 외부 클래스 객체명.new 내부 클래스 생성자();
// 외부 클래스를 Outer, 내부 클래스를 Inner로 가정
Outer outer = new Outer(); // 외부 클래스 객체 생성
Outer.Inner inner = outer.new Inner(); // 외부 클래스의 객체를 통해서 내부 클래스 객체 생성
GUI : Graphic User Interface의 약자, 사용자 화면용 애플리케이션을 의미한다.
익명 클래스 (anonymous inner class)
- 이름이 없는 클래스를 의미한다.
public interface EventListener {
public void onClick();
}
// 익명 클래스 생성 후 사용
public void setButtonListenerAnonymous() {
MagicButton button = new MagicButton();
button.setListener(new EventListener() {
@Override
public void onClick() {
System.out.println("Magic Button Clicked !!!");
}
}); // 메소드를 호출하는 과정이기에 중괄호 닫고 소괄호 닫고 ;까지
}
// 위와 같은 방식이지만 익명 클래스 재사용을 위해 객체를 생성
public void setButtonListenerAnonymous() {
MagicButton button = new MagicButton();
//익명 클래스의 객체를 생성해 클래스 내에서 재사용 가능
EventListener listener = new EventListener() {
@Override
public void onClick() {
System.out.println("Magic Button Clicked !!!");
}
};
button.setListener(listener);
}
- 익명 클래스 만드는 방법
- 익명 클래스가 필요한 부분에 new 인터페이스명()으로 생성자를 호출한 후 바로 뒤 중괄호 안에 인터페이스의 메소드를 구현한 후 중괄호를 닫는다. (일회성)
- 바로 익명 클래스를 구현해서 사용하면 다른 클래스나 메소드에서 재사용이 불가하기에 객체를 생성한 후 사용하는 방법도 있다.
- 객체 생성 후 사용하는 방식
// 객체를 생성해 익명 클래스를 재사용하는 방식
인터페이스명 변수명 = new 인터페이스명() {
// 인터페이스 메소드 구현
// 추가적인 멤버 변수 또는 메소드도 선언 가능
};
- 익명 클래스의 장점
- 클래스를 만들고 호출하면 메모리를 사용하는데 익명 클래스를 사용하면 메모리 사용을 줄여 애플리케이션 시작시 필요한 시간을 줄일 수 있다.
- 익명 클래스나 내부 클래스 모두 다른 클래스에서 재사용할 일이 없을 때 만들어야한다.
간단 내용 정리
1. Nested 클래스에 속하는 3가지 클래스에는 어떤 것들이 있나요?
ㅡ> Static nested class, Local inner class(내부 클래스), Anonymous inner class(익명 클래스)로 나뉜다.
2. Nested 클래스를 컴파일하면 Nested클래스 파일의 이름은 어떻게 되나요?
ㅡ> 외부클래스명$Nested클래스명.class
3. Static Nested 클래스는 다른 Nested 클래스와 어떤 차이가 있나요?
ㅡ> 클래스 선언 시 static으로 선언하는 여부와 객체 생성 방식의 차이가 있으며 Static Nested 클래스는 외부 클래스의 static 변수만 참조 가능하다.
4. StaticNested 클래스의 객체 생성은 어떻게 하나요?
ㅡ> 외부클래스명.StaticNested클래스명 객체명 = new 외부클래스명.StaticNested클래스의 생성자(); 로 생성한다.
5. 일반적인 내부 클래스의 객체 생성은 어떻게 하나요?
ㅡ> 외부클래스명 외부클래스객체명 = new 외부클래스 생성자();
외부클래스명.내부클래스명 내부클래스객체명 = 외부클래스객체명.new 내부클래스 생성자(); 로 외부 클래스 생성자를 사용해 내부 클래스 객체를 생성한다.
6. Nested 클래스를 만드는 이유는 무엇인가요?
ㅡ> 1. 한 곳에서만 사용되는 클래스를 논리적으로 묶어서 처리할 필요가 있을 때
2. 캡슐화가 필요할 때
3. 소스의 가독성과 유지보수성을 높이고 싶을 때
7. Nested 클래스에서 감싸고 있는 클래스의 private 로 선언된 변수에 접근할 수 있나요?
ㅡ> O, Static Nested 클래스를 제외한 두 클래스는 외부 클래스의 어떤 변수라도 참조할 수 있다.
8. 감싸고 있는 클래스에서 Nested 클래스에 선언된 private 로 선언된 변수에 접근할 수 있나요?
ㅡ> O, 외부 클래스에서 Nested 클래스에서 선언된 어떤 변수라도 참조할 수 있다.
출처: 이상민, <자바의 신 VOL.1> 로드북
'Java > 자바의 신 VOL.1' 카테고리의 다른 글
18. 이제 기본 문법은 거의 다 배웠으니 정리해봅시다 (1) | 2024.06.26 |
---|---|
17. 어노테이션이라는 것도 알아야한다 (0) | 2024.06.25 |
15. String (0) | 2024.06.25 |
14. 다 배운 것 같지만, 예외라는 중요한 것이 있어요 (0) | 2024.06.24 |
13. 인터페이스와 추상 클래스, enum (1) | 2024.06.22 |