ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • day21 - JAVA (inner class, static 내부 클래스, non-static 내부 클래스, 지역 내부 클래스, 무명 클래스)
    KIC/JAVA 2021. 7. 17. 00:57
    반응형

    [inner class]

    -> 클래스 내부에 다시 클래스를 선언해야 하는 경우가 있다.

     

    -> 이렇겍 클래스 내부에 들어 있는 클래스를 내부 클래스라고 한다.

     

    -> 내부 클래스(중첩 클래스: nested class)는 바깥 클래스(Outer class)의 다른 멤버(메소드, 멤버변수를 말함) 와 같은 클래스의 멤버가 된다.

     

    -> 내부 클래스는 다른 클래스 멤버와 마찬가지로 접근 속성을 가질 수도 있으며, 바깥 클래스 외부에서의 접근가능 여부는 접근 제어자에 의해 결정된다.

     

     

     

     

     

     

     

    [static 내부  클래스]

    -> static 내부 클래스(static inner class)는 내부 클래스의 객체를 바깥 클래스에 대해 독립적으로 만들 때 사용

     

    -> static 키워드를 가진 내부 클래스로, 멤버 변수나 메소드처럼 클래스 내부에서 선언

     

     

    -> 다른 클래스에서 Outer 클래스 내부의 클래스인 inner 클래스에 접근하기 위해서 객체를 생성할 때 다음과 같이 객체를 생성한다.

     

    -> 클래스 이름 다음에 바로 inner 클래스 이름 사용

     

     

     

     

     

     

     

     

    [non-static 내부  클래스]

    -> non-static 내부  클래스는 static 내부 클래스와 선언되는 위치는 같으나 static 선언되지 않은 내부클래스 이다.

     

    -> 다른 클래스에서 Outer 클래스의 내부클래스인 Inner 클래스에 접근하기 위해서 객체를 생성할 때는 먼저 바깥 클래스의 객체를 생성해서 그 레퍼런스를 가지고 내부 클래스의 객체를 생성한다.

     

     

     

     

     

     

     

     

    [지역 내부  클래스(local inner class)]

    -> static 과 non-static 내부 클래스가 바깥 클래스의 멤버의 위치에 선언되는 것에 비해, 지역 내부 클래스는 바깥 클래스의 메소드 안에 선언된 내부클래스이다.

     

     

     

     

     

     

    [무명  클래스(anonymous inner class)]

    -> 무명 내부 클래스는 지역 내부클래스의 변형으로 클래스 명을 갖지 않고 한번만 사용할 수 있다.

     

    -> 주로 이벤트 처리에 많이 사용된다.

     

     

     

     

     

     

     

     

     

    [내부 클래스 ex]

    package javaPro.java_inner;
    /*
     * 내부 클래스 예제
     * 
     *  인스턴스 내부클래스 :  (static)클래스 멤버를 가질 수 없다. 단 상수는 가능 
     *  static 내부클래스 : (static)클래스 멤버를 가질 수 있다.
     *  지역내부클래스        : 메서드 내에 선언된 클래스. 메서드 내부에서만 사용이 가능함.
     *  이름없는(무명의)내부클래스 : 클래스 없이 객체화 가능한 클래스
     *                        추상클래스,인터페이스 의 객체화 가능함.
     *                        
                     
     */
    class Outer1 {
        class instanceInner {// 인스턴스 내부 클래스
            int iv = 100;
            //static int cv = 10; // 클래스 멤버를 가질 수 없다.
            final static int MAX = 200;
        }
        static class StaticInner { //static 내부 클래스
            int iv = 300;
            static int cv = 400;
            final static int MAX = 500;
        }
    
        void method(){ // 지역 내부 클래스
            class LocalInner{
                int iv = 600;
                //static int cv = 700; //클래스 멤버를 가질 수 없다.
                final static int MAX = 700; // 상수는 가능하다.
            }
            LocalInner lc = new LocalInner();
            System.out.println(lc.iv); // 600
            System.out.println(lc.MAX); // 700
            System.out.println(LocalInner.MAX); // 700
        }
        void method2(){
            //LocalInner lc = new LocalInner(); // -> method() 메서드에서만 사용가능하다.
        }
    }
    
    public class InnerEx1 {
        public static void main(String[] args) {
            Outer1.StaticInner si = new Outer1.StaticInner();
            System.out.println(si.iv); //300
            System.out.println(Outer1.StaticInner.cv); // 400
            System.out.println(Outer1.StaticInner.MAX); // 500
            //Outer1.InstanceInner ii = new Outer1.InstanceInner();
            Outer1 outer = new Outer1();
            Outer1.instanceInner ii2 = outer.new instanceInner();
            System.out.println(ii2.iv); // 100
            System.out.println(Outer1.instanceInner.MAX);
            outer.method();
        }
    }

     

     

     

    [지역 내부 클래스 주의해야 할 점]

    -> 지역 내부 클래스에서 사용되는 메서드의 지역변수는 상수화(final) 되어야 한다.

     

    -> 즉, 로컬 변수인데 final이 아닌 지역 변수는 내부 클래스에 있는 메서드 내에서 사용할 수 없다.

    package javaPro.java_inner;
    
    //[지역 내부클래스에서 사용되는 메서드의 지역변수는 상수화(final) 되어야 한다.]
    
    class Outer2 {
        private static int outercv = 20;  //outercv 선언
    
        static StaticInner cv = new StaticInner();
    
        static InstanceInner cv2 = new Outer2().new InstanceInner(); 
        // cv2의 타입은 InstantceInner, outer2 객체 생성후 InstantceInner 메모리 할당
    
    
        static class StaticInner {              // static inner class
            int siv = new Outer2().outeriv;
            static int scv = outercv;
        
        }
    
        static StaticInner cv3 = new StaticInner();  // static inner 클래스도 이렇게 선언해서 사용 가능
    
        InstanceInner iv = new InstanceInner();
        private int outeriv = 10; // outeriv 선언
    
        class InstanceInner {
            int iiv = outeriv;
            int iiv2 = outercv;
        }
    
        void method(int pv) {
            //지역 내부클래스에서 사용되는 메서드의 지역변수는 상수화(final) 되어야 한다.
            int i = 0; // 이 i 처럼 메소드 안의 지역변수는 지역 내부클래스에서 사용되려면 final 이어야 한다.
    
    
            //pv++; // 이 코드를 실행하면 아래 print 문에서 오류가 난다.(final 은 한번 초기화 하고 수정이 불가능)
            //i++;  // 이 코드를 실행하면 아래 print 문에서 오류가 난다.(final 은 한번 초기화 하고 수정이 불가능)
            // -> 이 변수들을 수정시켰을 때 시스템 내에서 이 변수는 final이 아니라고 판단하게 되기 때문
    
    
            outeriv++; // 이건 가능
    
    
            class LocalInner { // 지역 내부 클래스
                int liv = outeriv; // 외부 클래스의 private 멤버 접근 가능
                int liv2 = outercv; // 외부 클래스의 private 멤버 접근 가능
                
                void method() {
                    //지역 내부 클래스에서 내부 클래스가 속한 메서드의 지역변수 변경 안됨
                    // i = 100;
                    //pv++;
    
                    System.out.println("i=" + i);
                    System.out.println("pv=" + pv);
                    System.out.println(liv + ", " + liv2);
                    System.out.println(outeriv + ", " + outercv); // 외부클래스의 private 멤버 접근 가능
                }
    
            }
            LocalInner li = new LocalInner();
            li.method();
    
        }
    
    }
    
    
    public class InnerEx2 {
        public static void main(String[] args) {
            Outer2 out = new Outer2();
            out.method(1);
    
            Outer2.InstanceInner i2 = out.new InstanceInner();
            System.out.println(i2.iiv);
            System.out.println(i2.iiv2);
    
            //Outer2.StaticInner i3 = new Outer2().StaticInner();
            //System.out.println(i3.siv);
            System.out.println(Outer2.StaticInner.scv);
        }
    }
    300x250

    댓글

Designed by Tistory.