티스토리 뷰

LANGUAGE/JAVA

[JAVA] 중첩 클래스

진심스테이크 2018. 6. 27. 17:03

 

중첩 클래스

- 두 클래스의 맴버들을 서로 쉽게 접근 할 수 있음

- 외부에는 불필요한 관계 클래스를 감춤으로써 코드의 복잡성 감소

ex) class ClassName { 

       class NestedClassName {

      

       }

     }

 

1. 멤버 클래스 : 클래스의 멤버로써 선언되는 중첩 클래스

- 클래스나 객체가 사용중이라면 언제든지 재사용 가능

ex) class A {

      class B {    }

    }

2. 로컬 클래스 : 메소드 내부에서 선언되는 중첩 클래스

- 메소드 실행 시에만 사용

- 메소드 실행 종료시 사라짐

ex) class A {

      static class B {    }

    }

 

 

- 인스턴스 멤버 클래스 : static 키워드 없이 선언된 클래스

   - 인스턴스 필드와 메소드만 선언 가능

   - 정적 필드와 메소드는 선언 불가

   - A 클래스 외부에서 인스턴스 멤버 클래스 B의 객체를 생성하려면 먼저 객체를 생성하고 B 객체를 생성해야함

 
 

- 정적 멤버 클래스 : static 키워드로 선언된 클래스

   - 모든 종류의 필드와 메소드 선언 가능

   - A 클래스 외부에서 정적 멤버 클래스 B의 객체를 생성하기 위해서는 A 객체를 생성할 필요가 없다

 

- 로컬 클래스 : 메소드 내에서 선언한 중첩 클래스

  - 접근 제한자(public, private) 및 static을 붙힐 수 없음 -> 메소드 내부에서만 사용되기 떄문

  - 인스턴스 필드와 메소드만 선언가능

  - 정적 필드와 메소드는 선언할 수 없음

//바깥 클래스
class A{
    A() {System.out.println("A 객체 생성됨");}
    
    //인스턴스 멤버 클래스
    class B{
        B() {System.out.println("B 객체가 생성됨");}
        int field1;
        //static int field2;
        void method1() { }
        //static void method2() { }
    }
    
    //정적 멤버 클래스
    static class C{
        C(){System.out.println("C 객체가 생성됨");}
        int field1;
        static int field2;
        void method1() { }
        static void method2() { }
        }
    
    void method() {
        //로컬 클래스
        class D{
            D(){System.out.println("D 객체가 생성됨");}
            int field1;
            //static int field2;
            void method1() { }
            //static void method2() { }
        }
        
        D d = new D();
        d.field1 = 3;
        d.method1();
    }
}

public class Main{
    public static void main(String[] args) {
        A a = new A();
        
        //인스턴스 멤버 클래스 객체 생성
        A.B b = a.new B();
        b.field1 = 3;
        b.method1();
        
        //정적 멤버 클래스 객체 생성
        A.C c = new A.C();
        c.field1 = 3;
        c.method1();
        A.C.field2 = 3;
        A.C.method2();
        
        //로컬 클래스 객체 생성을 위한 메소드 호출
        a.method();
    }
}

 


 

중첩 클래스의 접근 제한

- 바깥 필드와 메소드에서 사용 제한

public class A{
    //인스턴스 필드
    B field1 = new B();
    C field2 = new C();
    
    //인스턴스 메소드
    void method1() {
        B var1 = new B();
        C var2 = new C();
    }
    
    //정적 필드 초기화
    //static B field3 = new B();
    static C field4 = new C();
    
    //정적 메소드
    static void method2() {
        //B var1 = new B();
        C var2 = new C();
    }
    
    //인스턴스 멤버 클래스
    class B { }
    
    //정적 멤버 클래스
    static class C { }
}

 

- 멤버 클래스에서 사용 제한 

public class A{
    int field1;
    void method1() { }
    
    static int field2;
    static void method2() { }
    
    class B {
        void method() { //모든 필드와 메소드에 접근 가능
            field1 = 10;
            method1();
            
            field2 = 10;
            method2();
        }
    }
    
    static class C{
        void method() { 
            //인스턴스 필드와 메소드는 접근 불가
            //field1 = 10;
            //method1();
            
            field2 = 10;
            method2();
        }
    }
}

 

 

- 로컬 클래스에서 사용제한
  - 로컬 클래스에서 사용 가능한 것은 final로 선언된 매개 변수와 로컬 변수뿐

  - final 키워드가 있다면 로컬 클래스의 메소드 내부에 지역 변수로 복사

  - final 키워드가 없다면 로컬 클래스의 필드로 복사

  #자바 8 이후부터는 final 키워드를 붙히지 않아도 final 특성을 갖고 있음!

public class Outter {
    public void method(int arg) {
        int localVariable = 1;
        //arg = 100; //(x)
        //localVariable = 100; //(x)
        class Inner{
            public void method() {
                int result = arg + localVariable;
            }
        }
    }
}

 

 

- 중첩 클래스에서 바깥 클래스 참조 얻기

  - this 키워드를 사용하면 중첩 클래스의 객체가 참조됨

  - 중첩 클래스 내부에서 바깥 클래스의 객체 참조를 얻으려면 바깥 클래스의 이름을 this앞에 붙혀주면 됨

public class Outter {
    String field = "Outter-field";
    void method() {
        System.out.println("Outter-method");
    }
    
    class Nested{
        String field = "Nested-field";
        void method() {
            System.out.println("Nested-Method");
        }
        
        void print() {
            //중첩 객체 참조
            System.out.println(this.field);
            this.method();
            
            //바깥 객체 참조
            System.out.println(Outter.this.field);
            Outter.this.method();
        }
    }
}

//실행 클래스
public class OutterEx{
    public static void main(String[] args) {
        Outter outter = new Outter();
        Outter.Nested nested = outter.new Nested();
        nested.print();
    }
}

 

 

'LANGUAGE > JAVA' 카테고리의 다른 글

[JAVA] 삼항연산자  (0) 2019.07.12
[JAVA] ANONYMOUS OBJECT - 익명 객체  (0) 2018.06.28
[JAVA] ECLIPSE 단축키  (0) 2018.04.15
[JAVA] 경로  (0) 2018.04.15
[JAVA] INSTANCEOF  (0) 2018.04.15
댓글