내부 클래스

coding by 스플릿·2022년 1월 2일
0

Java1

목록 보기
39/44

정의

  • 클래스 내부에 선언된 클래스

사용 이유

  • 두 클래스가 긴밀하게 관계되어 있기 때문
  • 두 클래스의 멤버들 간에 쉽게 접근할 수 있다. ( 장점 )
  • 외부에 불필요한 클래스를 감춰 복잡성을 줄일 수 있다. ( 장점 )

특징

  • 내부 클래스는 외부 클래스를 제외하고는 잘 사용되지 않는 것이여야 한다.

종류

  • 인스턴스 클래스
    외부 클래스의 멤버변수 위치에 선언되며 외부클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언

  • 스태틱 클래스
    외부 클래스의 멤버변수 위치에 선어되며 스태틱 멤버와 스태틱 메서드에서 사용될 목적으로 선언

  • 지역 클래스
    외부 클래스의 메서드나 초기화 블럭 안에 선언되면 그 안에서만 사용 가능

  • 익명 클래스
    클래스의 선언과 객체의 생성을 동시에 하는 일회용 클래스
    • new 조상클래스이름(){...};
    • new 구현인터페이스이름(){...};
    • 특징
      • 이름이 없기에 생성자를 가질 수 없다.
      • 조상클래스나 인터페이스의 이름을 사용해서 정의하기에 상속과 구현을 같이 할 수 없다

사용 예시

  • 인스턴스 내부 클래스, 스태틱 내부 클래스
class Main{
    class inner_class{
        int instance_variable = 100;
//        static int static_variable = 200; 인스턴스 내부 클래스 스태틱 멤버변수를 사용할 수 없다
        final static int final_variable = 300;
    }
    static class static_inner_class{
        int instance_variable = 100;
        static int static_variable = 200;
        final static int final_variable = 300;
        static void show_something(){ System.out.println("something");}
    }

    public static void main(String[] args) {
//        System.out.println(inner_class.instance_variable); 사용할 수 없음
        System.out.println(inner_class.final_variable); //출력 : 300
//        System.out.println(static_inner_class.instance_variable); 사용 할 수 없음
        System.out.println(static_inner_class.static_variable); //출력 : 200
        System.out.println(static_inner_class.final_variable); //출력 : 300
        static_inner_class.show_something(); //출력 : something
    }
}
  • 인스턴스 내부클래스, 스태틱 내부 클래스
class Main{
    class instance_inner_class{} //인스턴스 내부 클래스
    static class static_inner_class{} //스태틱 내부 클래스

    //인스턴스 멤버 간에 서로 접근 가능
    instance_inner_class ic = new instance_inner_class();
    static static_inner_class sc = new static_inner_class();

    void instance_method(){ //인스턴스 메소드
        instance_inner_class iic = new instance_inner_class(); //접근 가능
        static_inner_class sc = new static_inner_class(); // 접근 가능
    }

    static void static_method(){ // 스태틱 메소드
        instance_inner_class iic = new instance_inner_class(); // error 스태틱 멤버는 인스턴스 멤버에 접근할 수 없음
        //인스턴스 내부 클래스에 접근하기 위해서는 외부 클래스 선언 이후 가능
        Main out_class = new Main();
        instance_inner_class inner_class = out_class.new instance_inner_class();
        static_inner_class sc = new static_inner_class(); // 접근 가능
    }
}
  • 지역 클래스
class Main{
    private int outer_iv = 1;
    static int outer_cv = 2;
    class Instance_inner_class{
        int i = outer_iv;
        int j = outer_cv;
    }
    static class Static_inner_class{
//        int i = outer_iv; // error 스태틱 내부클래스에서 외부 인스턴스 변수 사용 불가
        int j = outer_cv;
    }
    void my_method(){
        int instance_variable = 3;
        //jdk 1.8 이후부터는 지역클래스에 접근하는 지역 변수 앞에 final을 생략할 수 있다.
        final int final_variable = 4;
        class Local_inner_class{
//            static int static_variable = 5; // 스태틱 변수를 가질 수 없다
            static final int static_final_variable = 6; // 상수에는 static이 붙을 수 있다.
            int i = outer_iv;
            int j = outer_cv;
            int k = instance_variable; //jdk 1.8이전에는 error
            int l = final_variable;
        }
        System.out.println(Local_inner_class.static_final_variable); // 출력 : 6
        Local_inner_class lnc = new Local_inner_class();
        System.out.println(lnc.i); // 출력 : 1
        System.out.println(lnc.j); // 출력 : 2
        System.out.println(lnc.k); // 출력 : 3
        System.out.println(lnc.l); // 출력 : 4
    }

    public static void main(String[] args) {
        Main outer = new Main();
        outer.my_method();
    }
}
  • 익명 클래스
public class Main{
    public static void main(String[] args) {
        String msg = "msg";
        Parent_class anc = new Parent_class(){
            void show_something(String msg) {
                System.out.printf("Anonymous using Parent_class %s \n",msg);
            }
        };
        Myinterface ani = new Myinterface() {
            public void show_something(String msg){
                System.out.printf("Anonymous using Interface %s \n",msg);
            }
        };
        anc.show_something(msg);
        ani.show_something(msg);
    }
}
interface Myinterface{
    default void show_something(String msg){};
}
class Parent_class {
    void show_something(String msg){};
}

/*
출력:
Anonymous using Parent_class msg 
Anonymous using Interface msg 
*/

0개의 댓글