티스토리 뷰

반응형

 

지난 포스팅에서 '객체지향 프로그래밍'파트의 시리즈가 완강되어서

강의가 끝난줄 알았는데

추가 강의가 있어서 공부한 내용을 바탕으로 포스팅한다.

 

바로 들어가보자. 😊

 


🤔 내부 클래스의 제어자와 접근성이란?

✔ 내부 클래스의 제어자는 변수에 사용 가능한 제어자와 동일

 

class P {
    class InstanceInner {
        /*
        인스턴스 내부 클래스
         */
        int iv = 100;
//        static int cv = 100; // 에러!! static 변수를 선언할 수 없다.
        final static int CONST = 100; // final static은 상수이므로 허용
    }

    static class StaticInner {
        /*
        static 내부 클래스
        : static 내부 클래스에서는 외부 클래스의 인스턴스 멤버에 접근할 수 없다.
         */
        int iv = 200;
        static int cv = 200; // static 클래스만 static 멤버 정의할 수 있음.
    }

    void myMethod() {
        /*
        지역 내부 클래스
         */
        class LocalInner {
            int iv = 300;
//            static int cv = 300; // 에러!! static 변수를 선언할 수 없다.
            final static int CONST = 300; // final static은 상수이므로 허용
        }

        int i = LocalInner.CONST; // 이거는 가능 (왜냐? 지역이니까)
    }

    public static void main(String[] args) {
        System.out.println(InstanceInner.CONST);
        System.out.println(StaticInner.cv);
//        System.out.println(LocalInner.CONST); // 에러!! 왜냐 Local에서만 쓸 수 있으니까
    }
}

 

class P {
    class InstanceInner {
    }

    static class StaticInner {
    }

    InstanceInner iv = new InstanceInner(); // 인스턴스 멤버끼리는 직접 접근 가능
    static StaticInner cv = new StaticInner(); // static 멤버끼리는 직접 접근 가능

    static void staticMethod() { // static 멤버는 인스턴스 멤버에 접근 불가
//        InstanceInner obj1 = new InstanceInner(); //에러 왜냐? static => instance 안되니까
        StaticInner obj2 = new StaticInner();

        P outer = new P(); // 인스턴스 클래스는 외부 클래스 먼저 생성해야 생성가능
        InstanceInner obj1 = outer.new InstanceInner();
    }

    void instanceMethod() { // 인스턴스메서드에서는 인스턴스멤버와 static 멤버 모두 접근 가능
        InstanceInner obj1 = new InstanceInner();
        StaticInner obj2 = new StaticInner();
//        LocalInner lv = new LocalInner(); // 지역 내부 클래스는 외부에서 접근 불가
    }

    void Method() {
        class LocalInner {}
        LocalInner lv = new LocalInner();
    }
}

 

class Outer {
    private int outerIv = 0;
    static int outerCv = 0;

    class InstanceInner {
        int iiv = outerIv; // 외부 클래스의 private 멤버도 접근가능
        int iiv2 = outerCv;
    }

    static class StaticInner {
//        int siv = outerIv; // 에러 왜냐? static 클래스는 외부 클래스의 인스턴스 접근 불가
        static int scv = OuterCv;
    }

    void myMethod() {
        int lv = 0;
        final int LV = 0; // JDK 1.8부터 final 생략 가능

        class LocalInner {
            int liv = outerIv;
            int liv2 = outerCv;
            // 외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근가능
            int liv3 = lv;
            int liv4 = LV; // OK.
        }
    }
}

 

class Outer {
    private int outerIv = 0;
    private static int outerCv = 0;

    class InstanceInner { // 1. 인스턴스 메서드에는 외부 클래스 iv, cv 모두 접근 가능
        int iiv = outerIv; // 외부 클래스의 private 멤버도 접근 가능하다.
        int iiv2 = outerCv;
    }

    static class StaticInner { // 스태틱 메서드에는 외부 클래스 cv는 접근가능, iv는 접근불가
//        int siv = outerIv; // 스태틱 클래스는 외부 클래스의 인스턴스 멤버에 접근할 수 없다.
        static int scv = outerCv;
    }

    void myMethod() {
        int lv = 0; // 값이 바뀌지 않는 변수는 상수로 간주
        final int LV = 0; // JDK 1.8부터 final 생략 가능

        class LocalInner { // 2. 지역 내부 클래스를 감싸고 있는 메서드의 상수만 사용가능
            int liv = outerIv;
            int liv2 = outerCv;

            // 외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근가능
            int liv3 = lv; // JDK 1.8부터 허용
            int liv4 = LV; // OK.

            void method() {
                System.out.println(lv);
            }


        }

    }
}

 

 

class Tes {
    public static void main(String[] args) {
        Outer oc = new Outer();
        // 외부 크래스의 인스턴스를 먼저 생성해야 인스턴스 클래스의 인스턴스 생성 가능
        Outer.InstanceInner ii = oc.new InstanceInner();

        System.out.println("ii.iv : " + ii.iv);
        System.out.println("Outer.StaticInner.cv : " + Outer.StaticInner.cv);

        // 스태틱 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 됨.
        Outer.StaticInner si = new Outer.StaticInner();
        System.out.println("si.iv : " + si.iv);
    }
}

class Outer {
    class InstanceInner {
        int iv = 100;
    }

    static class StaticInner {
        int iv = 200;
        static int cv = 300;
    }

    void myMethod() {
        class LocalInner {
            int iv = 400;
        }
    }
}

 

위의 코드를 실행했을 때 다음의 클래스들이 생성된다.

생성된 클래스들

 

 

코드만 주구장창 올리는 이유는

선언 위치에 따른 변수의 종류만 알면

다 이해할 수 있는 내용이기 때문이다.

 

또한 개념으로 설명하는 것보다

코드를 직접 보면서 이해하는것이 훨씬 이해하기 쉽기 때문이다.

 

 

 

🤔 만약 위 내용들이 제대로 이해가 가지 않는다면

다음 포스팅의

선언 위치에 따른 변수의 종류 파트를

다시 읽어보기를 바란다.

해당 포스팅으로 이동

 

 


강의시간도 길고 처음엔 되게 어렵고 난해한 부분인데

위에서 말한 선언위치에 따른 변수의 종류만

잘 알고 있다면 딱히 이해하는데 어려움은 없을 것이다!!

 

절대 외우려 하지말고 이해하려 하자!!

(필자도 처음엔 선언 위치에 따른 변수의 종류를 외우려했으나

결국 여러 번 듣고 이해하는 것이 훨씬 빠르다는 것을 깨닫고 이해했다.)

 

그럼 오늘도 열공하자. 😊

반응형