16장 - 클래스 안에 클래스가 들어갈 수도 있구나
클래스 안의 클래스, Nested 클래스
- 코드 간단 표현 가능
- 자바 기반의 UI 처리 시 사용자 입력 및 외부 이벤트 처리하는 곳에서 많이 사용

package c.inner;
public class PublicClass {
}
class JustNotPublicClass {
}
- 파일 이름 : public한 클래스 이름 따서 정의해야함(컴파일 에러 방지)
Nested 클래스 사용 이유
- 한곳에서만 사용되는 클래스를 논리적으로 묶어 처리할 때 = Static nested 클래스 사용 이유
- 캡슐화 필요할 때 = 내부 구현 감추고 싶을 때 = 내부(inner) 클래스 사용 이유
- 소스 가독성과 유지보수성 높이고 싶을 때
Static nested 클래스 | 내부 클래스 |
내부 클래스처럼 접근 불가 | 감싸고 있는 외부 클래스의 어떤 변수도 접근 가능 private으로 선언된 변수도 접근 가능 |
- Nested 클래스 예시
package c.inner;
public class OuterOfStatic {
static class StaticNested {
private int value = 0;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
}
//생성되는 클래스 목록
OuterOfStatic.class
OuterOfStatic$StaticNested.class
- Static nested 클래스 예시
package c.inner;
public class NestedSample {
public static void main(String[] args) {
NestedSample sample = new NestedSample();
sample.makeStaticNestedObject();
}
public void makeStaticNestedObject() {
OuterOfStatic.StaticNested staticNested = new OuterOfStatic.StaticNested();
staticNested.setValue(3);
System.out.println(staticNested.getValue());
}
}
- 내부 클래스 예시
package c.inner;
public class OuterOfInner {
class Inner {
private int value = 0;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
}
package c.inner;
public class InnerSample {
public static void main(String[] args) {
InnerSample sample = new InnerSample();
sample.makeInnerObject();
}
public void makeInnerObject() {
OuterOfInner outer = new OuterOfInner();
OuterOfInner.Inner inner = outer.new Inner();
inner.setValue(3);
System.out.println(inner.getValue());
}
}
- Inner 클래스의 객체 생성 전에는 먼저 Inner 클래스를 감싸고 있는 OuterOfInner 라는 클래스의 객체 생성해야 함
- 캡슐화에 유용
- 하나의 클래스에 공통 작업 수행하는 클래스가 필요한데 다른 클래스에서는 그 클래스가 필요 없는 경우, 이런 내부 클래스 만들어 사용
- GUI 관련 프로그램 개발 시 많이 활용
GUI
- Graphic User Interface (사용자 화면용 애플리케이션)
- GUI에서 내부 클래스들이 많이 사용되는 경우 : 리스너(Listener) 처리 시
- 사용자가 버튼 클릭하거나 키보드 입력 시 이벤트(Event) 발생
- 어떤 버튼 눌릴 때 해야 하는 작업 정의하기 위해 내부 클래스 만들어 사용
- But 하나의 애플리케이션에서 어떤 버튼 눌릴 때 수행해야 하는 작업은 대부분 상이함
- ➡ 하나의 별도 클래스 만들어 사용하는 것보단 내부 클래스 만드는 게 훨씬 편함
- ➡ 내부 클래스보다 더 간단한 방법 = 익명 클래스
익명 클래스
- Anonymous class
- 이름 없는 클래스
package c.inner;
public class MagicButton {
public MagicButton() {
}
private EventListener listener;
public void setListener(EventListener listener) {
this.listener = listener;
}
public void onClickProcess() {
if(listener != null) {
listener.onClick();
}
}
}
package c.inner;
public interface EventListener {
public void onClick();
}
class MagicButtonListener implements EventListener {
public void onClick() {
System.out.println("Magic Button Clicked");
}
}
package c.inner;
public class AnonymousSample {
public static void main(String[] args) {
AnonymousSample sample = new AnonymousSample();
sample.setButtonListener();
}
public void setButtonListener() {
MagicButton button = new MagicButton();
MagicButtonListener listener = new MagicButtonListener();
button.setListener(listener);
button.onClickProcess();
}
}
- 화면 클릭 시 MagicButtonListener에 있는 onClick() 메서드 수행
(실제 GUI에서는 onClickProcess() 메서드 실행 x)
- 익명 클래스 예시
public void setButtonListenerAnonymous() {
MagicButton button = new MagicButton();
button.setListener(new EventListener() {
public void onClick() {
System.out.println("Magic Button Clicked");
}
});
button.onClickProcess();
}
- setListener() 메서드 호출하는 과정 내에 익명 클래스가 있기에 소괄호와 세미콜론 주의
- 익명 클래스는 클래스 이름도 없고 객체 이름도 없기에 다른 클래스나 메서드에서 참조 불가
- 해당 클래스 내에서 익명 클래스 재사용하려면 하기처럼 객체 생성해야
public void setButtonListenerAnonymousObject() {
MagicButton button = new MagicButton();
EventListener listener = new EventListener() {
public void onClick() {
System.out.println("Magic Button Clicked");
}
};
button.setListener(listener);
button.onClickProcess();
}
익명 클래스 장점
- 클래스 만들고 호출 시 해당 정보는 메모리에 올라감
= 클래스 많이 만들수록 많은 메모리 필요
= 애플리케이션 시작 시 더 많은 시간 소요 - 자바는 익명 클래스 같은 방법으로 객체 생성해 메모리 소모 줄일 수 있음
익명 클래스와 내부 클래스
- 둘 다 다른 클래스에서 재사용할 일이 없을 때 만들어야함
- Nested 클래스 특징
package c.inner;
public class NestedValueReference {
public int publicInt = 0;
protected int protectedInt = 1;
int justInt = 2;
private int privateInt = 3;
static int staticInt = 4;
static class StaticNested {
public void setValue() {
staticInt = 14;
}
}
class Inner {
public void setValue() {
publicInt = 20;
protectedInt = 21;
justInt = 22;
privateInt = 23;
staticInt = 24;
}
}
public void setValue() {
EventListener listener = new EventListener() {
public void onClick() {
publicInt = 30;
protectedInt = 31;
justInt = 32;
privateInt = 33;
staticInt = 34;
}
};
}
}
Static nested 클래스 | 내부 클래스와 익명 클래스 |
Static nested 클래스에서는 감싸고 있는 클래스의 static 변수만 참조 가능 Static nested 클래스가 static으로 선언되어 있기에 부모 클래스의 static하지 않은 변수는 참조 불가 만약 참조 시 컴파일 에러 발생 |
감싸고 있는 클래스의 어떤 변수라도 참조 가능 |
- 반대로의 참조 예시
package c.inner;
public class ReferenceAtNested {
static class StaticNested {
private int staticNestedInt = 99;
}
class Inner {
private int innerValue = 100;
}
public void setValue(int value) {
StaticNested nested = new StaticNested();
nested.staticNestedInt = value;
Inner inner = new Inner();
inner.innerValue = value;
}
}
- 각 클래스 객체 생성 후 그 값 참조 가능(해당 값이 private해도 접근 가능)
'Backend > Java' 카테고리의 다른 글
[자바의 신] 18장 (0) | 2022.07.26 |
---|---|
[자바의 신] 17장 (0) | 2022.07.25 |
[Java] String ➡ Long 타입으로 형변환 (0) | 2022.03.30 |
[Java] 정수 최대값, 최소값 구하기 (0) | 2022.03.28 |
[Java] int와 Integer 비교 (0) | 2022.03.21 |
댓글