내부클래스는 말 그대로 클래스 내부에 구현한 클래스이다.
내부클래스에는 4가지 유형이 존재한다.
- 인스턴스 내부 클래스
- 정적 내부 클래스
- 지역 내부 클래스
- 익명 내부 클래스
인스턴스 내부 클래스, 정적 내부 클래스 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
class OutClass{
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass() {
inClass = new InClass();
}
class InClass{ //1. 인스턴스 내부 클래스
int iNum = 100;
void inTest() {
System.out.println(num);
System.out.println(sNum);
}
}
public void usingInner() {
inClass.inTest();
}
static class InStaticClass{ //2. 정적 내부 클래스
int inNum = 100;
static int sInNum = 200;
void inTest() {
System.out.println(inNum);
System.out.println(sInNum);
System.out.println(sNum);
}
static void sTest()
{
// System.out.println(inNum); //static 매서드에서 사용할 수없다
//왜냐하면 static 매서드는 생성과 상관없이 불러올 수 있기 때문에
System.out.println(sInNum);
System.out.println(sNum);
}
}
}
public class InnerTest {
public static void main(String[] args) {
OutClass outClass = new OutClass();
outClass.usingInner();
OutClass.InClass myInClass = outClass.new InClass(); //인스턴스 내부 클래스 호출
myInClass.inTest();
System.out.println();
OutClass.InStaticClass sInClass = new OutClass.InStaticClass(); //정적 내부 클래스 호출
// 문법적으로 가능하지만 대부분 private으로 사용한다.
sInClass.inTest(); //inTest()는 static이 아니기 때문에 InStaticClass 인스턴스를 생성 후에 사용가능하다.
OutClass.InStaticClass.sTest();
}
}
|
cs |
지역 내부 클래스 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
class Outer{
int outNum = 100;
static int sNum = 200;
Runnable getRunnable(int i) {
int num = 100;
class MyRunnable implements Runnable{
@Override
public void run() {
//지역변수는 매서드가 호출되서 끝날 때 까지 유효한데 MyRunnable()이 반환되고 나면 메서드가 끝난 다음에도
//run은 계속 불릴수 있다. 따라서 유효하지않은 지역변수를 수정할 수 없다.
// num += 10; //num의 값 수정
// i = 200; //i 값 수정
System.out.println(num);
System.out.println(i);
System.out.println(outNum);
System.out.println(Outer.sNum);
}
}
return new MyRunnable();
}
}
public class LocalInnerClassTest {
public static void main(String[] args) {
Outer outer = new Outer();
Runnable runnable = outer.getRunnable(50); //getRunnable매소드가 호출되고 없어지면
//지역변수 i,num등 은 상수화되어서 계속 run()을 사용할 수 있게 해준다.
runnable.run();
}
}
|
cs |
익명 내부 클래스 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
class Outer2{
int outNum = 100;
static int sNum = 200;
Runnable getRunnable(int i) {
int num = 100;
return new Runnable () { //Runnable한 인터페이스를 구현해서 바로 run을 구현한 후 반환 한다는 의미
//클래스 이름이 없어진것이라고 할 수 있어서 익명이너클래스라고불린다.
@Override
public void run() {
// num+=i; 지역내부클래스 혹은 익명내부클래스에서 그 값을 변경할 수 없다. 따라서 상수화된다.
System.out.println(num);
System.out.println(i);
System.out.println(outNum);
System.out.println(Outer.sNum);
}
};
}
Runnable runner = new Runnable() {
@Override
public void run() {
System.out.println("test");
}
};
}
public class AnonymousInnerClassTest {
public static void main(String[] args) {
Outer2 outer = new Outer2();
outer.runner.run(); //익명 runner클래스에 바로접근
Runnable runnable = outer.getRunnable(50); //getRunnable매소드가 호출되고 없어지면
//지역변수 i,num등 은 상수화되어서 계속 run()을 사용할 수 있게 해준다.
runnable.run();
}
}
|
cs |
안드로이드 프로젝트를 하면서 익명 내부 클래스가 어떤 구조로 사용되는지 정확히 모르고 쓰고 있었는데 오늘 공부 한 것을 계기로 어떤 구조로 동작하는지 정확히 알게 되었다. 그리고 Runnable이라는 인터페이스에 대해서도 어느정도 배웠다.
'IT > Java' 카테고리의 다른 글
스트림 (0) | 2020.02.13 |
---|---|
람다식 (0) | 2020.02.13 |
컬렉션 프레임워크 06 Map인터페이스 (0) | 2020.01.09 |
컬렉션 프레임워크 05-2 Set인터페이스(TreeSet) (0) | 2020.01.09 |
컬렉션 프레임워크 05-1 Set인터페이스 (0) | 2020.01.09 |