상세 컨텐츠

본문 제목

중첩 클래스

기록 - 프로그래밍/Java

by wjjun 2024. 1. 19. 00:29

본문

 

사용목적

어떤 클래스는 여러 클래스와 관계를 맺지만

어떤 클래스는 특정 클래스와 관계를 맺습니다.

 

클래스가 여러 클래스와 관계를 맺는다면 독립적으로 선언하는 것이 좋지만

특정 클래스와 관계를 맺을 경우에는 관계 클래스를 내부에 선언하는 것이 좋습니다.

 

중첩클래스는 클래스 내부에 선언한 클래스입니다.

 

장점은 두 클래스의 멤버들을 서로 쉽게 접근이 가능합니다.

외부에는 불필요한 관계 클래스를 감추어서 코드의 복잡성이 감소합니다.

 

 

중첩 클래스

클래스의 멤버로 선언되는 중첩 클래스를 멤버 클래스

메서드 내부에서 선언되는 중첩 클래스를 로컬 클래스라고 합니다.

// 인스턴스 멤버 클래스
public class A {
    public class B { ... }
}

// 정적 멤버 클래스
public class A {
    static class B { ... }
}

// 로컬 클래스
public class A {
    void method() {
        class B { ... }
    }
}

인스턴스 멤버 클래스는 A객체를 생성해야만 B 중첩 클래스 사용이 가능합니다.

정적 멤버 클래스는 A 클래스로 바로 접근할 수 있는 B 중첩 클래스입니다.

로컬 클래스는 method() 가 실행될 때만 사용할 수 있는 B 중첩 클래스입니다.

 

인스턴스 멤버 클래스

인스턴스 멤버 클래스는 static 키워드 없이 선언된 클래스입니다.

A 클래스 외부에서 인스턴스 멤버 클래스 B 객체를 생성하려면 A 객체를 생성하고 B 객체를 생성해야 합니다.

class A {
    class B {
        B() { } // 생성자
        int field; // 인스턴스 필드
        void method1() { } // 인스턴스 메서드
        // static int field1; // 정적 필드 (X)
        // static void method1() // 정적 메서드 (X)
    }
}
A a = new A();
A.B b = a.new B();
b.field = 3;
b.method();

 

정적 멤버 클래스

static 키워드로 선언된 클래스를 의미합니다.

정적 멤버 클래스는 모든 종류의 필드, 메서드를 선언할 수 있습니다.

class A {
    static class C {
        C() { } // 생성자
        int field; // 인스턴스 필드
        void method1() { } // 인스턴스 메서드
        static int field1; // 정적 필드
        static void method1() // 정적 메서드
    }
}

 

A객체를 생성할 필요없이 C객체를 생성할 수 있습니다.

A.C c = new A.C();
c.field = 3; // 인스턴스 필드 사용
c.method(); // 인스턴스 메서드 호출
A.C.field1 = 3; // 정적 필드 사용
A.C.method1(); // 정적 메서드 호출

 

로컬 클래스

중첩 클래스는 메서드 내에서도 선언할 수 있습니다. 이것이 로컬 클래스입니다.

접근 제한자와 static을 붙일 수 없습니다. 로컬 클래스는 모두 메서드 내부에서만 사용되어 접근을 제어할 필요가 없습니다.

로컬 클래스 내부에는 인스턴스 필드와 메서드만 선언 가능하며 정적 필드, 메서드 선언이 불가합니다.

 

 

중첩 클래스 접근 제한

멤버 클래스가 인스턴스 또는 정적 선언되어 바깥 클래스의 필드와 메서드 사용이 제한됩니다.

 

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

인스턴스 멤버 클래스(B)는 바깥 클래스의 인스턴스 필드 초기값이나 인스턴스 메서드 객체 생성을 할 수 있지만

정적 필드의 초기값이나 정적 메서드에서는 객체를 생성할 수 없습니다.

 

(인스턴스 클래스 -> 정적 메서드, 정적 필드, 인스턴스 메서드, 인스턴스 필드 선언이 가능)

(정적 클래스 -> 정적 메서드, 정적 필드 선언이 가능)

 

반면, 정적 멤버 클래스(C)는 모든 필드의 초기값이나 모든 메서드 생성이 가능합니다.

 

 

로컬 클래스 사용제한

바깥 클래스의 필드, 메서드에서 사용할 수 없습니다.

로컬 값은 로컬 클래스 내부에 복사해두고 사용하는 값이기 때문입니다.

로컬 클래스에서 사용된 매개 변수와 로컬 변수는 모두 변하지 않는 final 특성을 갖습니다.

 

 

 

관련글 더보기

댓글 영역