Programing Language/Java

[Java] 중첩 클래스의 분류(Separation of Nested Class)

vinedpillar 2022. 7. 9. 01:28

중첩 클래스의 분류

  • 중첩 클래스는 선언 위치와 방식에 따라서 쓰임새가 나눠집니다.

  • 중첩 클래스의 종류는 아래와 같습니다.
    • 인스턴스 멤버 클래스(내부 클래스): 특정 클래스의 멤버로 선언된 클래스를 뜻합니다.
    • 스태틱 멤버 클래스(중첩 클래스): 특정 클래스의 정적 멤버로 선언된 클래스를 뜻합니다.
    • 로컬 클래스(지역 클래스): 특정 클래스의 메서드 내에 선언된 클래스를 뜻합니다.

 

 

 

인스턴스 멤버 클래스(Instance Member Class)

  • 인스턴스 멤버 클래스( = 내부 클래스)는 한 클래스 내부에 선언된 또 다른 클래스를 뜻합니다.

  • 클래스 내부에 선언되기 때문에 바깥 클래스의 인스턴스가 생성되어야만 내부 클래스의 인스턴스도 생성될 수 있습니다.

  • 따라서 인스턴스 멤버 클래스는 바깥 클래스의 모든 필드와 메서드를 활용할 수 있게 됩니다.

  • 인스턴스 멤버 클래스는 접근 제어자에 따라 접근할 수 있는 범위를 설정할 수 있습니다.
    • public: 다른 패키지에서 인스턴스 멤버 클래스를 사용할 수 있습니다.
    • (default): 같은 패키지 내에서만 인스턴스 멤버 클래스를 사용할 수 있습니다.
    • private: 바깥 클래스 내부에서만 인스턴스 멤버 클래스를 사용할 수 있습니다.

  • 인스턴스 멤버 클래스는 일반적으로 특정 클래스의 내부에서만 사용하기 위해 사용하기 때문에 private으로 선언됩니다.

  • 인스턴스 멤버 클래스는 필드, 컨스트럭터, 메서드에서 인스턴스를 생성하여 사용할 수 있으며, 일반 클래스와 같이 필드, 컨스트럭터, 메서드를 멤버로 가질 수 있습니다.
    (자바17 부터는 정적 필드와 정적 메서드를 선언 가능)
인스턴스 멤버 클래스 사용 예시

public class OuterClass {
    class InnerClass {
    	// 인스턴스 멤버 클래스 필드
        int innerField;
        
        // 인스턴스 멤버 클래스 컨스트럭터
        InnerClass() {
        
        }
        
        // 인스턴스 멤버 클래스 메서드
        void innerMethod() {
            System.out.println("인스턴스 멤버 클래스 메서드");
        }
    }
    
    // 바깥 클래스의 메서드
    void useInnerClass() {
    	// 인스턴스 멤버 클래스의 인스턴스 생성
        InnerClass ic = new InnerClass();
        ic.innerMethod();
    }
}

// 실행 클래스
public class InnerClassExample {
    public static void main(String[] args) {
    	// 바깥 클래스 객체 생성
        OuterClass oc = new OuterClass();
        
        // 안쪽 클래스 객체 생성
      	OuterClass.InnerClass ic = oc.new InnerClass();
        
        // 메서드 사용
        oc.useInnerClass();        
        ic.innerMethod();
    }
}

 

 

 

 

스태틱 멤버 클래스(Static Member Class)

  • 스태틱 멤버 클래스(= 중첩 클래스)는 한 클래스 내부에 정적(static)으로 선언된 또 다른 클래스를 뜻합니다.

  • 클래스 내부에 있지만 정적으로 선언되기 때문에 바깥 클래스의 인스턴스가 생성되지 않아도 중첩 클래스의 인스턴스를 생성할 수 있습니다.
    (접근은 바깥클래스를 통해 접근)

  • 바깥 클래스의 인스턴스가 생성되지 않았을 경우가 있기 때문에 스태틱 멤버 클래스는 바깥 클래스의 정적 필드와 정적 메서드만 접근이 가능합니다.

  • 스태틱 멤버 클래스 역스 접근 제어자에 따라 접근할 수 있는 범위를 설정할 수 있습니다.
    • public: 다른 패키지에서 스태틱 멤버 클래스를 사용할 수 있습니다.
    • (default): 같은 패키지 내에서만 스태틱 멤버 클래스를 사용할 수 있습니다.
    • private: 바깥 클래스 내부에서만 스태틱 멤버 클래스를 사용할 수 있습니다.

  • 스태틱 멤버 클래스는 일반적으로 바깥 클래스와 함께 다른 클래스와도 상호작용을 고려하기 때문에 default나 public으로 선언됩니다.

  • 스태틱 멤버 클래스는 바깥 클래스 내부 어디서든 인스턴스를 생성할 수 있으며, 마찬가지로 필드, 컨스트럭터, 메서드를 멤버로 가질 수 있습니다.
스태틱 멤버 클래스 사용 예시

public class OuterClass {
    static class NestedClass {
    	// 스태틱 멤버 클래스 필드
        int nestedField;
        
        // 스태틱 멤버 클래스 컨스트럭터
        NestedClass() {
        
        }
        
        // 스태틱 멤버 클래스 메서드
        void nestedMethod() {
            System.out.println("스태틱 멤버 클래스 메서드");
        }
    }
    
    // 정적으로 선언된 바깥 클래스의 메서드
    static void useNestedClass() {
    	// 스태틱 멤버 클래스의 인스턴스 생성
        InnerClass ic = new InnerClass();
        ic.innerMethod();
    }
}

// 실행 클래스
public class NestedClassExample {
    public static void main(String[] args) {
        // 바깥 클래스 인스턴스 생성 없이 바로 안쪽 클래스 인스턴스 생성
      	OuterClass.NestedClass nc = oc.new NestedClass();
        
        // 메서드 사용      
        nc.innerMethod();
    }
}

 

 

 

 

 

로컬 클래스(Local Class)

  • 로컬 클래스는 한 클래스 내부의 컨스트럭터나 메서드 내부에 선언된 또 다른 클래스를 뜻합니다.

  • 로컬 클래스는 컨스트럭터나 메서드가 동작할 때만 인스턴스를 생성할 수 있습니다.

  • 로컬 클래스는 바깥 클래스의 변수를 활용할 수 있지만 이 경우 활용 되는 로컬 변수는 final의 특성을 가져 로컬 클래스 내부에서 바깥 클래스의 변수 값을 변경하지 못하도록 제한하고 있습니다.

  • 로컬 클래스 역시 일반 클래스와 같이 필드, 컨스트럭터, 메서드를 멤버로 가질 수 있습니다.
    (자바17 부터 정적 필드와 정적 메서드의 선언 가능)
로컬 클래스 사용 예시

public class OuterClass {
    // 바깥 클래스의 메서드
    void useLocalClass() {
    	// 메서드 내부에 클래스 선언
        class LocalClass {
            // 로컬 클래스 필드
            int lcField = 1;
            
            // 로컬 클래스 컨스트럭터
            LocalClass() {
            
            }
            
            // 로컬 클래스 메서드
            void localClassMethod() {
            	System.out.println("로컬 클래스 메서드 실행");
            }
        }
        
        // 로컬 클래스 인스턴스 생성
        LocalClass lc = new Localclass();
        
        // 바깥 클래스의 메서드 실행 내용
        System.out.println(lc.lcField);
        lc.localClassMethod();
    }
}

// 실행 클래스
public class LocalClassExample {
    public static void main(String[] args) {
    	// 바깥 클래스 객체 생성
        OuterClass oc = new OuterClass();
        
        // 클래스에서 메서드 사용
        oc.useLocalClass();
    }
}