[기본 개념] 2 | (8.1) 내부클래스, 익명클래스
1> 내부클래스란?
2> 내부클래스의 종류와 특징
3> 내부클래스의 선언
4> 내부클래스의 제어자와 접근성
5> 익명클래스(anonymous class)
1. 내부클래스란?
내부클래스는 클래스 내에 선언된 클래스이다. 클래스 내에 선언하는 이유는 두 클래스가 서로 긴밀한 관계이기 때문이다.
내부클래스를 사용하면 두 클래스의 멤버들 간에 서로 쉽게 접근할 수 있다는 장점과 외부에는 불필요한 클래스를 감춤으로 코드의 복잡성을 줄일 수 있다.
내부클래스의 장점
- 내부클래스에서 외부클래스의 멤버들을 쉽게 접근할 수 있다.
- 코드의 복잡성을 줄일 수 있다.
class A { . . . } class B { . . . } |
----> | class A { // 외부클래스 . . . class B { // 내부클래스 . . . } . . . } |
이때 내부클래스인 B는 다른 클래스에서 잘 사용되지 않아야 한다.
2. 내부클래스의 종류와 특징
내부클래스는 마치 변수를 선언하는 것과 같은 위치에 선언할 수 있으며, 선언위치에 따라 다음과 같이 구분된다.
내부클래스 | 특징 |
인스턴스클래스 (instance class) |
외부클래스의 멤버변수 선언위치에 선어하며, 외부클래스의 인스턴트멤버처럼 다뤄진다. 주로 외부클래스의 인스턴스멤버들과 관련된 작업에 사용된다. |
스태틱클래스 (static class) |
외부클래스의 멤버변수 선언위치에 선언하며, 외부클래스의 static멤버처럼 다뤄진다. 주로 외부클래스의 static멤버, 특히 static메서드에서 사용된다. |
지역클래스 (local class) |
외부클래스의 메서드나 초기화블럭 안에 선언하며, 선언된 영역 내부에서만 사용된다. |
익명클래스 (anonymous class) |
클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용) |
3. 내부클래스의 선언
아래의 오른쪽 코드에는 외부클래스에 3개의 서로 다른 종류의 내부클래스를 선언했다.
선언된 위치에 따라 인스턴스클래스, 스태틱클래스, 지역클래스로 나뉜다. 그리고 각 내부클래스의 선언위치에 따라 같은 선언위치의 변수와 동일한 유효범위(scope)와 접근성(accessibility)을 갖는다.
class Outer { int iv = 0 ; static int cv = 0 ; void myMethod( ) { int lv = 0 ; } } |
<----> | class Outer { class InstanceInner { } static class StaticInner { } void myMethod( ) { class LocalInner { } } } |
4. 내부클래스의 제어자와 접근성
내부클래스도 클래스이기 때문에 abstract나 final과 같은 제어자를 사용할 수 있고, private, protected과 접근제어자도 사용할 수 있다.
예제/InnerEx1.java
public class InnerEx1 {
class InstanceInner {
int iv = 100;
// static int cv = 100; // error. staic변수를 선언할 수 없다.
final static int CONST = 100; // final static은 상수이므로 허용
}
static class StaticInner {
int iv = 200;
static int cv = 200; // static클래스만 static멤버를 정의할 수 있다.
}
void myMethod() {
class LocalInner {
int iv = 300;
// static int cv = 300; // error. static변수를 선언할 수 없다.
final static int CONST = 300; // final static은 상수이므로 허용
}
}
public static void main(String[] args) {
System.out.println(InstanceInner.CONST);
System.out.println(StaticInner.cv);
}
}
실행결과
100
200
내부클래스 중에 스태틱클래스(StaticInner)만 static멤버를 가질 수 있다. 다만 final static이 동시에 붙은 변수는 상수(constant)이므로 모든 내부클래스에서 정의가 가능하다.
예제/InnerEx2.java
public class InnerEx2 {
class InstanceInner { }
static class StaticInner { }
// 인스턴스멤버 간에는 서로 직접접근이 가능하다.
InstanceInner iv = new InstanceInner();
// static멤버 간에는 서로 직접접근이 가능하다.
static StaticInner cv = new StaticInner();
static void staticMethod() {
// static멤버는 인스턴스멤버에 직접접근할 수 없다.
// InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// 굳이 접근하려면 아래와 같이 객체를 생성해야 한다.
// 인스턴스클래스는 외부클래스를 먼저 생성해야만 생성할 수 있다.
InnerEx2 outer = new InnerEx2();
InstanceInner obj1 = outer.new InstanceInner();
}
void instanceMethod() {
// 인스턴스메서드에서는 인스턴스멤버와 static멤버 모두 접근 가능하다.
InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// 메서드 내에 지역적으로 선언된 내부클래스는 외부에서 접근할 수 없다.
// LocalInner lv = new LocalInner();
}
void myMethod() {
class LocalInner { }
LocalInner lv = new LocalInner();
}
}
인스턴스클래스는 외부클래스의 인스턴스멤버를 객체생성 없이 바로 사용할 수 있다. (외부클래스의 인스턴스변수가 private일지라도 가능하다.) 그러나 스태틱클래스는 외부클래스의 인스턴스멤버를 객체생성 없이 사용할 수 없다.
마찬가지로 인스턴스클래스는 스태틱클래스의 멤버들을 객체생성없이 사용할 수 있지만, 스태틱클래스에서는 인스턴스클래스의 멤버들을 객체생성없이 사용할 수 없다.
5. 익명클래스(anonymous class)
익명클래스는 다른 내부클래스들과는 달리 이름이 없다. 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한 번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스이다.
new 조상클래스이름( ) {
// 멤버선언
}
또는
new 구현인터페이스이름( ) {
// 멤버선언
}
이름이 없기 때문에 생성자도 가질 수 없으며, 오직 단 하나의 클래스를 상속받거나 단 하나의 인터페이스만을 구현할 수 있다.
예제/InnerEx6.java
public class InnerEx6 {
Object iv = new Object() { void method() { } }; // 익명클래스
static Object cv = new Object() { void method() { } }; // 익명클래스
void myMehtod() {
Object lv = new Object() { void method() { } }; // 익명클래스
}
}
이 예제를 컴파일하면 다음과 같이 4개의 클래스파일이 생성된다.
InnerEx6.class
InnerEx6$1.class <-- 익명클래스
InnerEx6$2.class <-- 익명클래스
InnerEx6$3.class <-- 익명클래스
익명클래스는 이름이 없기 때문에 '외부 클래스명$숫자.class'의 형식으로 클래스 파일명이 결정된다.
출처 | Java의 정석 (남궁 성)
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
[기본 개념] 3 | (1.2) Try-catch 문, 예외 발생 (0) | 2021.11.24 |
---|---|
[기본 개념] 3 | (1.1) 예외처리 구조 (0) | 2021.11.23 |
[기본 개념] 2 | (7.3) 인터페이스, 디폴트 메서드 (0) | 2021.11.21 |
[기본 개념] 2 | (7.2) 인터페이스 다형성, 장점 (0) | 2021.11.20 |
[기본 개념] 2 | (7.1) 인터페이스 상속, 구현, 다중상속 (0) | 2021.11.20 |