전공/객체지향프로그래밍

[객체지향프로그래밍][Java] Nested Classes

Campus Coder 2023. 6. 10. 21:52
728x90
반응형

Nested Classes

중첩 클래스

다른 클래스의 범위 내에서 정의되는 클래스

클래스의 특성, 멤버의 특성 모두 가짐

접근 지정자 4가지 전부 사용 가능

class OuterClass {
    class InnerClass {
        //필드
        // static 멤버 가질 수 없음
    }

    static class StaticNestedClass {
        // 필드
        // 모든 멤버 가질 수 있음
    }
}
class OuterClass2 {
    // static InnerClass a = new InnerClass();
    static StaticNestedClass b = new StaticNestedClass();
    
    InnerClass c = new InnerClass();
    StaticNestedClass d = new StaticNestedClass();

    static void staticMethod() {
        // InnerClass e = new InnerClass();
        StaticNestedClass f = new StaticNestedClass();
    }

    void instanceMethod() {
        InnerClass g = new InnerClass();
        StaticNestedClass h = new StaticNestedClass();
    }
    
    class InnerClass {}
    
    static class StaticNestedClass {}
}

static 메소드나 변수는 내부 클래스 객체 생성 불가

static은 외부 클래스에 접근할 때 처음에 실행되는데, 내부 클래스는 외부 클래스 객체가 생성될 때(static 실행 이후) 생성해야 하기 때문

 

내부 클래스에서 외부 클래스의 필드에 접근하기(내부 클래스에 겹치는 이름이 있을 경우)

InnerClass -> 외부클래스.this.필드

StaticNestedClass -> 외부클래스.필드

 

같은 클래스 내에서 static 메소드가 static이 아닌 필드에 접근하지 못하는 것과 같은 맥락

 

StaticNestedClass에서도 마찬가지로 외부 클래스의 non-static 필드에 접근 불가

 

중첩 클래스 사용

OuterClass oc = new OuterClass();

// 바깥 클래스 객체에 대한 내부 클래스 객체 생성
OuterClass.InnerClass ic = oc.new InnerClass();
ic.nonStaticField = 1;
ic.nonStaticMethod();

// '바깥 클래스.정적 중첩 클래스' 형태로 레퍼런스 선언 및 객체 생성
OuterClass.StaticNestedClass snc = new OuterClass.StaticNestedClass();
snc.nonStaticField = 1;
snc.nonStaticMethod();
OuterClass.StaticNestedClass.staticField = 1;
OuterClass.StaticNestedClass.staticMethod();

 

 

Local Classes

메소드 내에 정의되어있는 클래스

class AClass {
    void method() {
        class LocalClass {
            int nonStaticField;
            //static int staticField;
            LocalClass() {}
            void nonStaticMethod() {}
            //static void staticMethod() {}
        }
        LocalClass lc = new LocalClass();
        lc.nonStaticField = 1;
        lc.nonStaticMethod();
    }
    
    void method(final int arg) {
        final int localVariable = 0;
        class LocalClass {
            void method() {
                int a = arg;
                int b = localVariable;
                // localVariable = 1;
                // arg = 1;
            }
        }
    }
}

LocalClass필드에 static 멤버 가질 수 없음

 

LocalClass에서 외부클래스의 필드 사용 -> 외부클래스.this.필드

 

class AClass {
    AnInterface method() {
        class LocalClass implements AnInterface {
            public void method() {}
        }
        return new LocalClass();
    }
}

interface AnInterface {
    public void method();
}

함수의 리턴값으로 LocalClass 객체를 리턴할 수 있음

리턴할 타입을 상속받거나 Object 타입으로 리턴할 객체의 타입 지정

 

 

Anonymous Classe

class SuperClass {
    void method() { System.out.println("method in Super Class"); }
}

public class AnonymousExample {
    private static void print(SuperClass obj) { obj.method(); }

    public static void main(String[] args) {
        print(new SuperClass() {
            @Override
            void method() {
                System.out.println("method in Anonymous Class");
            }
        });
    }
}
new SuperClass() { @Override void method() { System.out.println("method in Anonymous Class"); } }

클래스 또는 인터페이스를 즉시 오버라이딩 가능

{ } 블록 안은 실제 클래스와 같이 private 접근 지정자까지 사용 가능

728x90
반응형