0. 딴소리



제 주력 언어는 C++ 입니다. 졸업작품을 만드느라 급하게 안드로이드 프로그래밍을 하고 있습니다. JAVA를 하다가 생소한 것들만 골라서 포스팅 할 예정입니다. 


그리고 오늘의 생소한 것은 중첩 클래스 입니다.


각막염에 걸렸습니다. 앞이 잘 안보여요. 초점이 잘 안잡히니 작업하기가 시원치않네요.




0. 개요


오늘 다룰 내용은 중첩 클래스입니다.


하나의 자바 소스파일에는 여러 개의 클래스를 작성할 수 있지만, 하나의 클래스 파일(.class)에는 반드시 하나의 컴파일된 자바 클래스만이 포함되어야 합니다.


만약 하나의 클래스 파일에 여러개의 클래스를 정의한 경우 컴파일러가 별도의 파일을 생성합니다. 


다음과 같이 생성되는 것을 확인할 수 있습니다.




총 4개의 클래스 파일이 생성되게 됩니다.


1. ClassA.class

2. ClassB.class

3. ClassC.class

4. ClassC$ClassD.class


이때 ClassD는 ClassC 내에 작성된 내부 클래스입니다.


하나의 자바 소스 파일에 작성된 클래스 중 오직 한 클래스만 public으로 선언할 수 있습니다. public으로 선언한 클래스의 이름은 소스파일의 이름과 동일하게 작성해야 합니다.





1. 중첩 클래스 란?


클래스 내부에 선언된 클래스입니다. 


중첩 클래스를 사용함으로써 얻을 수 있는 장점들 입니다.


① 한 곳에서만 사용되는 클래스를 그룹화 한다.


     클래스가 다른 클래스를 사용할 때(= 기능하나를 구현하면서 필요한 클래스들) 유용하다면, 클래스에 그 클래스를 포함시켜 함께 유지하는 것이 논리적입니다.

또한, 패키지가 간결해 질 수 있습니다.


② 내부 클래스에서 외부 클래스에 쉽게 접근할 수 있다.


    내부 클래스에서 외부 클래스에 쉽게 접근할 수 있습니다. 단, 외부클래스에서 내부 클래스를 접근 할 때에는 직접 객체를 만들어 접근해야 합니다.


③ 읽기 쉽고 유지 보수가 쉬운 코드를 작성할 수 있다.


    최상위 클래스와 하위 클래스는 사용되는 위치에 가깝게 배치됩니다.




중첩 클래스는 두가지로 나뉩니다.


중첩된 클래스 (클래스 내부의 클래스) 는 정적인지, 비 정적인지에 따라 다른 멤버가 엑세스할 수 있는 지가 정해집니다.


1. 정적 클래스 (static class)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ClassA {
    int a;
    
    ClassA(){}
    
    public static void main(String[] args){
    }
 
    static private class InnerClass{
        InnerClass(){a = 4;}    //오류 발생
    }
}
cs




2. 비 정적 클래스 (inner class)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ClassA {
    int a;
    
    ClassA(){}
    
    public static void main(String[] args){
    }
 
    private class InnerClass{
        InnerClass(){a = 4;}
    }
}
cs





2. 정적 중첩 클래스


객체 클래스 또는 객체 클래스에 정의돈 메소드를 직접 참조할 수 없으며, 객체 참조를 통해서만 사용할 수 있습니다.


정적 중첩 클래스는 다른 최상위 클래스와 마찬가지로 외부 클래스 (및 다른 클래스)의 인스턴스 멤버와 상호 작용합니다. 실제로, 정적 중첩 클래스는 행동 상으로는 패키징 편의를 위해 다른 최상위 클래스에 중첩 된 최상위 클래스입니다.


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
package example;
 
public class ClassA {
    
    ClassA(){}
    
    public static void main(String[] args){
    }
 
    static class InnerClass{
    }
}
 
class ClassC{
    ClassC(){}
    
    void run(){
        
        ClassA.InnerClass inner = new ClassA.InnerClass();
    }
}
 
cs








3. 비 정적 클래스(내부 클래스/Inner class)



비 정적 클래스는 두가지 종류가 있습니다.


1. 익명 클래스


  이름이 없다는 것을 제외하고는 로컬 클래스와 같습니다. 한번만 사용해야 하는 경우에 사용하세요.


2. 로컬 클래스


   메서드 내부에 정의된 클래스입니다.



1. 익명 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
public class ClassA {
    
    interface HelloWorld{
        public void say();
    }
    
    ClassA(){}
    
    public static void main(String[] args){
        HelloWorld hello = new HelloWorld(){
            public void say(){
                System.out.println("hi");
            }
        };    
        
        hello.say();
    }
}
 
cs




2. 로컬 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ClassA {
    
    ClassA(){}
    
    public void fun(){
        class LocalClass{
 
        }
    }
 
    public static void main(String[] args){
 
    }
}
cs



지역 클래스는 modifier가 default이거나 final 또는 abstract로만 선언될 수 있습니다.

지역클래스를 포함하는 메소드 안에서만 객체를 생성할 수 있고, 메서드의 실행이 끝나면 해당 지역 클래스가 메모리에서 사라지게 됩니다.






4. 정리



내부 클래스의 종류


내부클래스 

선언위치 

비고 

멤버 내부 클래스

클래스 안에 선언(필드와 동일한 위치) 

사용 빈도 높음 

로컬 내부 클래스 

메서드 안에 선언 (메서드 내에 위치)

사용 빈도 낮음 

정적 내부 클래스 

클래스 안에 선언(필드와 동일한 위치) 

사용 빈도 낮음 

익명 클래스 

클래스 또는 메서드 안에 둘 다 가능 

AWT, Swing 이벤트에 사용 빈도 높음 





+ Recent posts