Inner Class(내부 클래스)

박윤택·2022년 5월 19일
3

JAVA

목록 보기
7/14

정의

클래스 내부에 선언한 클래스로 이 클래스를 감싸고 있는 외부 클래스와 밀접한 연관이 있는 경우가 많고, 다른 외부 클래스에서 사용할 일이 거의 없는 경우에 사용한다. 중첩 클래스라고도 한다. 내부 클래스에서 외부 클래스의 멤버들에 쉽게 접근할 수 있고 코드의 복잡성도 줄일 수 있다.

종류사용 가능한 변수
인스턴스 내부 클래스외부 인스턴스 변수, 외부 전역 변수
정적 내부 클래스외부 전역 변수
지역 내부 클래스외부 인스턴스 변수, 외부 전역변수
익명 내부 클래스외부 인스턴스 변수, 외부 전역변수
[내부 클래스 종류]

인스턴스 내부 클래스

public class Outer {
    private int num = 1;
    private static int staticNum = 2;

    public Outer(){
        // Outer 생성자에서 Inner 생성자 호출
        inner = new Inner();
    }

    private Inner inner;
	
//  인스턴스 내부 클래스는 캡슐화를 지키기 위해 웬만하면 private로!
    private class Inner {
        private int inum = 3;
//        사용 불가!, 외부 클래스가 생성되어야 내부 클래스가 생성될 수 있기 때문
//        private static int staticiNum = 4;
        private static final int STATIC_FINAL = 5;
        public void innerTest() {
            System.out.println(num); // 외부 인스턴스 변수 출력
            System.out.println(staticNum); // 외부 static 변수 출력
            System.out.println(inum); // 내부 인스턴스 변수 출력
//            System.out.println(staticiNum); // 내부 static 변수 출력 불가
            System.out.println(STATIC_FINAL); // 내부 상수 출력
        }
        public Inner(){}
    }


    public void outerTest() {
        inner.innerTest();
    }
}

    public void outerTest() {
        inner.innerTest();
    }
}

public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outerTest();
    }
}
  • 외부 클래스가 생성되어야 내부 클래스를 사용할 수 있다.
  • 인스턴스 내부 클래스 내에서 정적 변수 사용 불가능하나 상수는 사용 가능하다

정적 내부 클래스

public class Outer {
    private int num = 1;
    private static int staticNum = 2;

    public Outer(){
        // Outer 생성자에서 Inner 생성자 호출
        inner = new Inner();
    }

    private Inner inner;
    
//	내부 정적 클래스(static)
    public static class Inner {
        private int inum = 3;
        private static int staticiNum = 4;
        private static final int STATIC_FINAL = 5;
        public void innerTest() {
//            System.out.println(num); // 외부 인스턴스 변수 출력 불가, 정적 내부 클래스가 먼저 메모리에 할당되었기 때문에
            System.out.println(staticNum); // 외부 static 변수 출력
            System.out.println(inum); // 내부 인스턴스 변수 출력
            System.out.println(staticiNum); // 내부 static 변수 출력
            System.out.println(STATIC_FINAL); // 내부 상수 출력
        }
        public Inner(){}
        
        public static void innerStaticTest() {
//            System.out.println(inum); // static 메서드 내에서는 인스턴스 변수 사용 불가
            System.out.println(staticNum);
            System.out.println(staticiNum);
            System.out.println(STATIC_FINAL);
        }
    }


    public void outerTest() {
        inner.innerTest();
    }
}

public class Main {
	public static void main(String[] args) {
    
    }
}


public class Main {
    public static void main(String[] args) {
        Outer.Inner inner = new Outer.Inner();
        inner.innerTest();
    }
}
  • 정적 내부 클래스에서는 외부 클래스의 인스턴스 멤버 변수 접근 불가하다.
  • 외부 클래스의 생성과 무관하게 내부 클래스를 사용하고 싶을때 사용한다.
    - 단, 내부 클래스의 접근제어자는 public으로설정한다.

지역 내부 클래스

외부 클래스의 멤버가 아닌 메서드 내에서 정의되는 클래스로 지역 변수와 유사하다. 메서드가 호출될 때 메모리에 로딩되기 때문에 static 키워드를 붙일 수 없다!

public class Outer { //외부 클래스
    int num = 5;
    void test() {
        int num2 = 6;
        class LocalInClass { //지역 내부 클래스, 접근 제어자 사용 불가(해당 지역 내에서만 사용가능하기 때문에 큰 의미가 없어서)
            void getPrint() { // 접근 제어자 사용 가능
                System.out.println(num);
                System.out.println(num2);
            }
        }
        LocalInClass localInClass = new LocalInClass();
        localInClass.getPrint();
    }
}

익명 내부 클래스

클래스의 선언과 객체 생성을 동시에 하기 때문에 하나의 객체만 생성 가능하고 일회용이다. 익명이라는 점을 빼면 지역 내부 클래스와 유사하다. 만약 일회성으로 내부 클래스를 사용하려면 코드를 더 간결하게 만들 수 있다.

interface Person {
    String name = "test";
    void getName();
}

public class Main {
    public static void main(String[] args) {
        Person obj = new Person() {
            public void getName() {
                System.out.println("내 이름은 " + name);
            }
        };
        obj.getName();
    }
}

0개의 댓글