본문 바로가기
IT/Java

내부클래스

by 어센트 2020. 1. 10.

내부클래스는 말 그대로 클래스 내부에 구현한 클래스이다.

내부클래스에는 4가지 유형이 존재한다.

 

  1. 인스턴스 내부 클래스
  2. 정적 내부 클래스
  3. 지역 내부 클래스
  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