본문 바로가기

Java

[Java] 중첩 클래스

728x90

중첩 클래스

1. 내부 클래스(Inner Class)
- 클래스 또는 메소드 안에 또 다른 클래스를 만드는 것
- 내부 클래스는 외부 클래스의 모든 멤버를 자신의 멤버처럼 사용(private 멤버 접근 가능)
- static 내부 클래스를 제외한 내부 클래스는 항상 외부 클래스 객체를 통해서 생성
(외부클래스에서 객체 생성해서 생성한 객체를 통해 내부클래스 객체 생성 가능)

class OuterClass {
    private int num1 = 10;

    public void method1() {
        System.out.println("num1 : " + num1);
    }

    public void printInner() {
        InnerClass innerClass = new InnerClass(); 
        innerClass.method2();
    }

    class InnerClass { // 내부 클래스
        private int num2 = 20;
        public void method2() {
            System.out.println("OuterClass.num1 : " + num1); // 외부 클래스의 멤버에 접근 가능
            System.out.println("InnerClass.num2 : " + num2);
        }

    }
}

public class InnerClass {
    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        outerClass.method1();
        outerClass.printInner();
        System.out.println();
        // 외부클래스 객체 생성해서 생성한 객체를 통해 내부클래스 객체 생성 가능
        OuterClass.InnerClass innerClass = outerClass.new InnerClass(); 
        innerClass.method2();
    }
}


2. 로컬 클래스(Local Class)
- 메소드 안에서 정의된 클래스(메소드 안에서만 사용할 수 있음)
- 외부 클래스의 모든 멤버에 접근 가능(private 멤버도 접근 가능)
- 지역변수는 접근할 수 없지만, final로 선언된 상수는 접근이 가능

public class LocalClass {
    private int num1 = 10;

    public void method1() {
        int num2 = 20;

        class Local { // 메소드 내 생성된 클래스(Local class)
            // 자바8부터 final을 붙이지 않아도 final로 자동 생성됨.
            private int num3 = 30;
            private final int num4 = 40;

            public void method2() {
                System.out.println("num1 : " + num1); // 외부클래스의 모든 멤버에 접근가능
                System.out.println("num2 : " + num2);
                System.out.println("num3 : " + num3);
            }
        }
        Local local = new Local();
        local.method2();

    }
    public static void main(String[] args) {
        LocalClass localClass = new LocalClass();
        localClass.method1();
    }
}



3. static 클래스(static class)
- 내부 클래스가 static으로 정의
- 외부 클래스에 관계없이 객체를 생성할 수 있음

public class StaticClass {
    static class Static { // static 클래스
        int num = 0;
        public void plus(){
            num++;
        }
    }

    public static void main(String[] args) {
        // 외부클래스 객체를 생성하지 않아도 내부클래스 객체를 생성할 수 있음.
        StaticClass.Static Static = new StaticClass.Static(); // 외부클래스.내부클래스 참조변수 = new 외부클래스.내부클래스
        Static.plus();
        Static.plus();
        System.out.println(Static.num);
    }
}



4. 익명 클래스(anonymous class)
- 클래스를 정의하지 않고 객체를 정의(생성)할 때 사용
- 일회용 클래스이므로 재활용이 불가능

interface Inter1 {
    void method1();
}

class TestClass1 implements Inter1 {
    @Override
    public void method1() {
        System.out.println("Inter1을 구현한 클래스");
    }
}

interface Inter2 {
    String method2();
}

class TestClass2 implements Inter2 {
    @Override
    public String method2() {
        return "실명 클래스";
    }
}

class TestClass3 {
    // Inter2 인터페이스를 구현한 클래스의 객체를 모두 매개변수로 전달받음.
    public void method3(Inter2 inter2) { 
        System.out.println(inter2.method2());
    }
}

public class Anonymous {
    public static void main(String[] args) {
        TestClass2 testClass2 = new TestClass2();
        TestClass3 testClass3 = new TestClass3();

        testClass3.method3(testClass2); // Inter2를 구현한 클래스의 객체 매개변수로 전달

        // 참조변수를 만들지 않고 바로 객체 생성해서 매개변수로 전달, 필요할 때만 만들어지고 사라짐.
        testClass3.method3(new TestClass2() { 
           @Override
            public String method2() { // Inter2의 method2() 오버라이드
                return "익명 객체!";
            }
        });
    }
}

 

 

728x90