09_중첩 선언과 익명 객체

Tasker_Jang·2024년 3월 10일
0
post-custom-banner

09_중첩 선언과 익명 객체

1. 중첩 클래스

캡슐화 강화: 중첩 클래스를 사용하면 외부 클래스의 내부에서만 사용되는 클래스를 외부로부터 숨길 수 있습니다. 이로써 구현의 세부 사항을 캡슐화하고 외부에서의 접근을 제한할 수 있습니다.

가독성 향상: 관련된 클래스를 함께 그룹화하면 코드의 가독성이 향상됩니다. 외부 클래스와 관련이 깊은 클래스들이 함께 정의되어 있으면, 코드를 이해하고 유지보수하는 데 도움이 됩니다.

네임스페이스 관리: 중첩 클래스를 사용하면 클래스의 이름 충돌을 방지하고 명확한 네임스페이스를 유지할 수 있습니다. 중첩 클래스의 이름이 외부 클래스와 관련이 있으면, 그 관계가 명확해집니다.

코드의 논리 구조 강조: 중첩 클래스를 사용하면 클래스 간의 논리적인 관계를 코드 구조에 반영할 수 있습니다. 특히 특정 클래스가 다른 클래스와 강하게 결합되어 있을 때, 중첩 클래스로 표현하면 더 명확하게 표현할 수 있습니다.

2. 인스턴스 멤버 클래스

인스턴스 멤버 클래스(Instance Member Class)는 다른 클래스의 멤버로 선언되어, 해당 클래스의 인스턴스를 생성할 때만 사용할 수 있는 클래스를 의미합니다. 이 클래스는 주로 외부 클래스의 인스턴스와 관련이 깊고, 해당 인스턴스의 속성이나 메서드에 접근해야 할 때 유용하게 사용됩니다.

일반적으로 인스턴스 멤버 클래스는 외부 클래스 내부에서만 사용되기 때문에 private 접근 제한을 갖는 것이 일반적입니다. 이렇게 함으로써 외부에서 직접적으로 접근할 수 없고, 외부 클래스의 메서드나 속성을 통해서만 사용할 수 있게 됩니다. 이는 캡슐화를 강화하고 외부에서의 클래스의 내부 구현 세부사항을 감추는 데 도움이 됩니다.

예시로 보면:

public class OuterClass {
    private int outerField;

    // 인스턴스 멤버 클래스
    private class InnerClass {
        private int innerField;

        public InnerClass(int innerField) {
            this.innerField = innerField;
        }

        public void doSomething() {
            // 외부 클래스의 인스턴스 변수에 접근 가능
            System.out.println("Outer field: " + outerField);
            // 내부 클래스의 인스턴스 변수에 접근 가능
            System.out.println("Inner field: " + innerField);
        }
    }

    // 외부 클래스의 메서드에서 내부 클래스 사용 예시
    public void useInnerClass() {
        InnerClass innerInstance = new InnerClass(42);
        innerInstance.doSomething();
    }
}

위의 예제에서 InnerClassOuterClass의 인스턴스 멤버로 선언되어 있고, private로 접근 제한되어 있습니다. 그리고 useInnerClass 메서드에서 외부에서 내부 클래스의 인스턴스를 생성하고 활용하고 있습니다.

3. 정적 멤버 클래스

정적 멤버 클래스(Static Member Class)는 static 키워드와 함께 클래스의 멤버로 선언되어, 해당 클래스의 인스턴스와 독립적으로 사용할 수 있는 클래스를 나타냅니다. 이 클래스는 외부 클래스의 인스턴스에 종속되지 않으며, 정적으로 선언된 클래스이므로 외부 클래스의 static 멤버에 접근할 수 있습니다.

아래는 정적 멤버 클래스의 간단한 예제입니다:

public class OuterClass {
    private static int outerStaticField;

    // 정적 멤버 클래스
    public static class StaticInnerClass {
        private int innerField;

        public StaticInnerClass(int innerField) {
            this.innerField = innerField;
        }

        public void doSomething() {
            // 외부 클래스의 정적 변수에 접근 가능
            System.out.println("Outer static field: " + outerStaticField);
            // 내부 클래스의 인스턴스 변수에 접근 가능
            System.out.println("Inner field: " + innerField);
        }
    }

    // 외부 클래스의 메서드에서 정적 내부 클래스 사용 예시
    public static void useStaticInnerClass() {
        StaticInnerClass innerInstance = new StaticInnerClass(42);
        innerInstance.doSomething();
    }
}

4. 로컬 클래스

로컬 클래스(Local Class)는 주로 생성자 또는 메서드 내부에서 선언되어 사용되는 클래스를 의미합니다. 이 클래스는 특정 메서드나 생성자 내에서만 유효하며, 해당 메서드나 생성자의 지역 변수에 접근할 수 있습니다.

로컬 클래스는 메서드 내에 선언되므로 해당 메서드 내에서만 인스턴스를 생성하고 사용할 수 있습니다. 이로써 클래스의 유효 범위가 제한되어 메서드 외부에서는 직접적인 접근이 불가능하며, 해당 메서드의 기능을 보조하거나 특정 구현을 위한 클래스를 제한된 범위에서 사용할 때 유용합니다.

예를 들어서:

public class OuterClass {
    public void someMethod() {
        // 로컬 클래스
        class LocalInnerClass {
            private int innerField;

            public LocalInnerClass(int innerField) {
                this.innerField = innerField;
            }

            public void doSomething() {
                System.out.println("Inner field: " + innerField);
            }
        }

        // 메서드 내에서 로컬 클래스 사용 예시
        LocalInnerClass localInstance = new LocalInnerClass(42);
        localInstance.doSomething();
    }
}

5. this

중첩 클래스(Inner Class)에서 바깥 클래스(Outer Class)의 객체를 얻기 위해서는 바깥 클래스의 이름에 this를 붙여주면 됩니다. 이는 중첩 클래스 내부에서 바깥 클래스의 인스턴스에 접근할 때 사용됩니다.

예를 들어, 내부 클래스에서 바깥 클래스의 인스턴스 변수에 접근하려면 다음과 같이 사용할 수 있습니다:

public class OuterClass {
    private int outerField = 10;

    // 내부 클래스
    public class InnerClass {
        private int innerField = 20;

        public void accessOuterField() {
            // 바깥 클래스의 객체를 얻어서 바깥 클래스의 인스턴스 변수에 접근
            int result = OuterClass.this.outerField;
            System.out.println("Outer field: " + result);
        }

        public void accessInnerField() {
            System.out.println("Inner field: " + innerField);
        }
    }

    public static void main(String[] args) {
        OuterClass outerInstance = new OuterClass();
        InnerClass innerInstance = outerInstance.new InnerClass();

        innerInstance.accessOuterField(); // 바깥 클래스의 인스턴스 변수에 접근
        innerInstance.accessInnerField(); // 내부 클래스의 인스턴스 변수에 접근
    }
}

6. 중첩 인터페이스

중첩 인터페이스(Nested Interface)는 클래스 내부에서 선언된 인터페이스를 나타냅니다. 이러한 인터페이스는 주로 특정 클래스와 강하게 결합되어 있으며, 해당 클래스의 기능을 보완하거나 특정한 용도로 사용될 때 유용합니다.

중첩 인터페이스는 외부 클래스의 멤버로 선언되므로, 접근 제어자를 사용하여 외부에서의 접근을 제한할 수 있습니다. 이는 캡슐화의 개념을 강화하고, 해당 인터페이스가 특정 클래스와 밀접한 관련이 있다는 것을 나타낼 수 있습니다.

예를 들어:

public class OuterClass {
    // 중첩 인터페이스
    public interface NestedInterface {
        void someMethod();
    }

    // 외부 클래스의 멤버 메서드
    public void useNestedInterface(NestedInterface nestedInstance) {
        nestedInstance.someMethod();
    }
}

7. 익명 객체

익명 객체(Anonymous Object)는 이름이 없는 객체를 말하며, 익명 자식 객체(Anonymous Child Object)는 부모 클래스를 상속받아 생성된 익명 객체를 나타냅니다. 이러한 익명 객체는 주로 한 번만 사용되어 다른 객체와의 간단한 상호작용이 필요한 경우에 사용됩니다.

익명 객체는 주로 인터페이스나 추상 클래스의 인스턴스를 생성할 때 유용하게 사용됩니다. 익명 객체를 사용하면 코드를 간결하게 작성할 수 있고, 필요한 로직을 직접 정의하여 인스턴스를 생성할 수 있습니다.

예를 들어, 익명 자식 객체를 생성하는 경우:

// 부모 클래스 또는 인터페이스 정의
interface MyInterface {
    void someMethod();
}

public class Main {
    public static void main(String[] args) {
        // 익명 자식 객체 생성
        MyInterface myObject = new MyInterface() {
            @Override
            public void someMethod() {
                System.out.println("Anonymous child object's implementation of someMethod");
            }
        };

        // 익명 자식 객체의 메서드 호출
        myObject.someMethod();
    }
}

8. 익명 구현 객체

익명 구현 객체(Anonymous Implementation Object)는 주로 인터페이스를 구현하여 생성되는 객체를 말합니다. 이는 주로 인터페이스의 메서드를 구체적으로 정의하고 해당 인터페이스를 구현한 객체를 생성할 때 사용됩니다.

익명 구현 객체는 특정 클래스의 새로운 서브클래스를 생성하지 않고도 간단한 인터페이스 구현을 제공할 수 있습니다. 주로 한 번만 사용되어야 하는 간단한 구현체를 생성할 때 효과적입니다.

예를 들어:

// 부모 인터페이스 정의
interface MyInterface {
    void someMethod();
}

public class Main {
    public static void main(String[] args) {
        // 익명 구현 객체 생성
        MyInterface myObject = new MyInterface() {
            @Override
            public void someMethod() {
                System.out.println("Anonymous implementation of someMethod");
            }
        };

        // 익명 구현 객체의 메서드 호출
        myObject.someMethod();
    }
}
profile
터널을 지나고 있을 뿐, 길은 여전히 열려 있다.
post-custom-banner

0개의 댓글