언어(Language)/Java

[Java] 자바 내부 클래스(Inner Class) 개념 정리 및 사용법

잇트루 2022. 9. 15. 00:00
반응형

내부 클래스 (Inner Class)

내부 클래스는 클래스 내에 선언된 클래스이다. 외부 클래스와 내부 클래스가 서로 연관되어 있을 때 사용한다. 내부 클래스를 사용하면 외부 클래스의 멤버들에 쉽게 접근할 수 있다.

내부 클래스는 외부 클래스 안에 선언하여 사용한다는 점을 제외하면 일반 클래스와 큰 차이점이 없다. 즉, 외부 클래스와 내부 클래스가 연관되어 있을 때, 사용성을 높이기 위한 수단이다.

또한, 불필요한 데이터를 감출 수 있어 캡슐화(Encapsulation)를 하는데 유용하다.

 

내부 클래스는 인스턴스 내부 클래스, 정적 내부 클래스, 지역 내부 클래스 세 가지로 구분할 수 있다.

class OuterClass {
    // 필드

    class InnerClass {
        // 인스턴스 내부 클래스
    }

    static class StaticInnerClass {
        // 정적 내부 클래스
    }

    void methodEx() {
        class LocalInnerClass {
            // 지역 내부 클래스
        }
    }
}

인스턴스 내부 클래스

외부 클래스의 멤버 변수 선언위치에 선언해야 하며, 외부 인스턴스 변수와 외부 전역변수를 사용할 수 있다.

 

정적 내부 클래스

외부 클래스의 멤버 변수 선언위치에 선언해야 하며, 외부 전역 변수만을 사용할 수 있다.

 

지역 내부 클래스

외부 클래스의 메서드나 초기화블럭 안에 선언한다. 외부 인스턴스 변수와 외부 전역변수를 사용할 수 있다.

 

익명 내부 클래스

클래스의 선언과 객체의 생성을 동시에 할 수 있는 일회용 익명 클래스로, 외부 인스턴스 변수와 외부 전역변수를 사용할 수 있다.

 

인스턴스 내부 클래스와 정적 내부 클래스를 묶어 멤버 내부 클래스라고도 한다.

 

인스턴스 내부 클래스

인스턴스 내부 클래스는 객체 내부에 멤버의 형태로 존재한다. 외부 클래스의 모든 접근 지정자의 멤버에 접근할 수 있다. 즉, 외부 클래스의 멤버 변수가 private일 지라도 내부 클래스에서 외부 클래스의 멤버 변수에 접근할 수 있다.

또한, 인스턴스 내부 클래스는 반드시 외부 클래스를 생성한 이후에 사용해야 한다. 즉, 정적 변수와 정적 메서드는 인스턴스 내부 클래스에서 선언할 수 없다.

class OuterClass {
    private String str1 = "외부 클래스 인스턴스 변수입니다.";
    private static String str2 = "외부 클래스 정적 변수입니다.";

    private InnerClass innerClass; // 내부 클래스 변수 선언

    // 외부 클래스 생성자
    public OuterClass() {
        innerClass = new InnerClass();
    }

    // 인스턴스 내부 클래스
    class InnerClass {
        String innerStr1 = "내부 클래스 인스턴스 변수입니다.";
        // static String innerStr2 = "내부 클래스 정적변수는 선언 불가능";

        void Test() {
            System.out.println(str1);
            System.out.println(str2);
            System.out.println(innerStr1);
        }
    }

    public void testClass() {
        innerClass.Test();
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();

        outer.testClass();
    }
}
// Output
외부 클래스 인스턴스 변수입니다.
외부 클래스 정적 변수입니다.
내부 클래스 인스턴스 변수입니다.

 

정적 내부 클래스

정적 내부 클래스는 내부 클래스가 외부 클래스의 존재와 무관하게 정적 변수를 사용할 수 있다.

인스턴스 내부 클래스와 동일하게 클래스의 멤버 변수 위치에 정의하며 static 키워드를 사용한다.

class OuterClass {
    private String str1 = "외부 클래스 인스턴스 변수입니다.";
    private static String str2 = "외부 클래스 정적 변수입니다.";

    void getPrintInstance() {
        System.out.println("인스턴스 메서드");
    }

    static void getPrintStatic() {
        System.out.println("정적 메서드");
    }

    static class StaticInnerClass {
        void test() {
            System.out.println(str2);
            getPrintStatic();

            // 인스턴스 변수 및 인스턴스 메서드는 사용 불가
            // System.out.println(str1);
            // getPrintInstance();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass.StaticInnerClass innerClass = new OuterClass.StaticInnerClass();
        innerClass.test();
    }
}
//출력
외부 클래스 정적 변수입니다.
정적 메서드

 

지역 내부 클래스

지역 내부 클래스는 메서드 내에서 정의되는 클래스이다. 지역 내부 클래스는 지역 변수와 유사하게 메서드 내부에서만 사용이 가능하다. 따라서 메서드 안에서 선언 후에 객체를 생성하여 사용한다.

class OuterClass {
    String str1 = "외부 클래스 인스턴스 변수";

    void test() {
        String str2 = "지역 변수";

        // 지역 내부 클래스
        class LocalInnerClass {
            void getPrint() {
                System.out.println(str1);
                System.out.println(str2);
            }
        }
        // 메서드 내에서 객체를 생성 후 사용
        LocalInnerClass localInnerClass = new LocalInnerClass();
        localInnerClass.getPrint();
    }
}

public class Main{
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.test();
    }
}
// 출력
외부 클래스 인스턴스 변수
지역 변수
반응형