[Java] 내부 클래스란? (inner class)
2022. 2. 21. 01:45ㆍBack-end/Java
- 클래스 내부에 선언한 클래스로 이 클래스를 감싸고 있는 외부 클래스와 밀접한 연관이 있는 경우가 많다
- 다른 외부 클래스에서 사용할 일이 거의 없는 경우에 내부 클래스로 선언해서 사용한다
- 중첩 클래스라고도 한다
- 인스턴스 내부 클래스, 정적(static) 내부 클래스, 지역(local) 내부 클래스, 익명(anonymous) 내부 클래스가 있다
인스턴스 내부 클래스
- 내부적으로 사용할 클래스를 선언 (private으로 선언)
- 외부 클래스가 생성된 후 생성됨 (정적 내부 클래스와 다름)
- private이 아닌 내부 클래스는 다른 외부 클래스에서 생성할 수 있다
OutClass outClass = new OutClass();
OutClass.InClass inClass = outClass.new InClass();
인스턴스 내부 클래스 예제 코드
package ch01;
class OutClass {
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass() {
inClass = new InClass(); // 내부 클래스 생성
}
private class InClass {
int iNum = 30;
void inTest() {
System.out.println("(외부 클래스의 인스턴스 변수) OutClass num = " + num);
System.out.println("(외부 클래스의 스태틱 변수) OutClass num = " + sNum);
System.out.println("(내부 클래스의 인스턴스 변수) InClass num = " + iNum);
}
}
public void usingClass() {
inClass.inTest(); // 내부 클래스 변수를 사용하여 메서드 호출
}
}
public class InnerTest {
public static void main(String[] args) {
OutClass outClass = new OutClass();
outClass.usingClass();
}
}
정적 내부 클래스
- 외부 클래스 생성과 무관하게 사용할 수 있다
- 정적 변수, 정적 메서드 사용
정적 내부 클래스 예제 코드 (인스턴스 내부 클래스 예제 코드에 이어서 작성)
package ch01;
class OutClass {
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass() {
inClass = new InClass(); // 내부 클래스 생성
}
private class InClass {
int iNum = 30;
void inTest() {
System.out.println("(외부 클래스의 인스턴스 변수) OutClass num = " + num);
System.out.println("(외부 클래스의 스태틱 변수) OutClass num = " + sNum);
System.out.println("(내부 클래스의 인스턴스 변수) InClass num = " + iNum);
}
}
public void usingClass() {
inClass.inTest(); // 내부 클래스 변수를 사용하여 메서드 호출
}
static class InStaticClass {
int inNum = 100;
static int inStaticNum = 200;
void inTest() { //정적 클래스의 일반 메서드
// 외부 클래스의 인스턴스 변수는 사용할 수 없음
System.out.println("(내부 클래스의 인스턴스 변수) InStaticClass num = " + inNum);
System.out.println("(내부 클래스의 스태틱 변수) InStaticClass num = " + inStaticNum);
System.out.println("(외부 클래스의 스태틱 변수) InClass num = " + sNum);
}
static void sTest() { // 정적 클래스의 스태틱 메서드
// 외부, 내부 클래스의 인스턴스 변수는 사용할 수 없음
System.out.println("(내부 클래스의 스태틱 변수) InStaticClass num = " + inStaticNum);
System.out.println("(외부 클래스의 스태틱 변수) InClass num = " + sNum);
}
}
}
public class InnerTest {
public static void main(String[] args) {
// OutClass outClass = new OutClass();
// outClass.usingClass();
// 외부 클래스 생성하지 않고 바로 정적 내부 클래스 생성
OutClass.InStaticClass inStaticClass = new OutClass.InStaticClass();
System.out.println("정적 내부 클래스 일반 메서드 호출");
inStaticClass.inTest();
System.out.println("정적 내부 클래스의 스태틱 메서드 호출");
OutClass.InStaticClass.sTest();
}
}
지역 내부 클래스
- 지역 변수와 같이 메서드 내부에서 정의하여 사용하는 클래스
- 메서드의 호출이 끝나면 메서드에 사용된 지역 변수의 유효성은 사라진다
- 메서드 호출 이후에도 사용해야 하는 경우가 있을 수 있으므로 지역 내부 클래스에서 사용하는 메서드의 지역 변수나 매개 변수는 final로 선언된다
package ch01;
class Outer {
Runnable getRunnable(int i) {
int num = 100;
class MyRunnable implements Runnable {
@Override
public void run() {
// i = 123; -> error
// num = 456; -> error
System.out.println(i);
System.out.println(num);
}
}
return new MyRunnable();
}
}
public class AnonumousInnerTest {
public static void main(String[] args) {
Outer outer = new Outer();
Runnable runnable = outer.getRunnable(10);
runnable.run();
}
}
- MyRunnable 클래스를 사용하려면 getRunnable 메서드를 호출해서 생성된 개체를 반환 받아야 한다
익명 내부 클래스
- 이름이 없는 클래스 (위 지역 내부 클래스의 MyRunnable 클래스 이름은 실제로 호출되는 경우가 없음)
- 클래스의 이름을 생략하고 주로 하나의 인터페이스나 하나의 추상 클래스를 구현하여 반환한다
- 인터페이스나 하나의 추상 클래스 자료형의 변수에 직접 대입하여 클래스를 생성하거나 지역 내부 클래스의 메서드 내부에서 생성하여 반환할 수 있다
- 안드로이드 위젯의 이벤트 핸들러에 활용된다
package ch01;
class Outer {
Runnable getRunnable(int i) {
int num = 100;
return new Runnable() {
@Override
public void run() {
// i = 123; -> error
// num = 456; -> error
System.out.println(i);
System.out.println(num);
}
};
}
Runnable runnable2 = new Runnable() {
@Override
public void run() {
System.out.println("Runnable 이 구현된 익명 클래스 변수");
}
};
}
public class AnonumousInnerTest {
public static void main(String[] args) {
Outer outer = new Outer();
Runnable runnable1 = outer.getRunnable(10);
runnable1.run();
outer.runnable2.run();
}
}
- 익명 내부 클래스가 제일 많이 쓰인다고 한다
이상으로 자바의 내부 클래스에 대해 알아보았다.
반응형
'Back-end > Java' 카테고리의 다른 글
[Java] 스트림(Stream) - reduce() (0) | 2022.02.26 |
---|---|
[Java] 스트림(Stream) (0) | 2022.02.24 |
[Java] 객체 지향 프로그래밍 vs 람다식 (0) | 2022.02.23 |
[Java] 함수형 인터페이스로 람다식 구현 (0) | 2022.02.22 |
[Java] 함수형 프로그래밍 - 람다식(Lambda expression) (1) | 2022.02.22 |