코딩 스쿨 Java

언어선택 : HTMLCSSJAVAJAVASCRIPTMYSQLSQL PHP

Java Inner Classes

자바 내부 클래스 (Java Inner Classes): 개념 및 사용법

자바에서 **내부 클래스(Inner Class)**는 클래스 내부에 정의된 클래스를 말하며, 외부 클래스(Outer Class)와 밀접한 관계를 가집니다. 내부 클래스는 외부 클래스의 멤버(변수, 메서드)에 쉽게 접근할 수 있으며, 이를 통해 코드의 구조화와 캡슐화를 더욱 강화할 수 있습니다. 자바는 다양한 유형의 내부 클래스를 지원하며, 각각의 사용 목적과 특징이 다릅니다.

이 글에서는 자바의 내부 클래스의 개념과 종류, 사용법, 예제에 대해 다룹니다.

1. 내부 클래스(Inner Class)란?

  • *내부 클래스(Inner Class)**는 하나의 클래스가 다른 클래스 내부에 선언된 클래스를 말합니다. 내부 클래스는 외부 클래스의 멤버에 접근할 수 있고, 외부 클래스와 강하게 결합되어 있어 특정 작업을 보다 간결하고 논리적으로 구현할 수 있습니다.

내부 클래스의 주요 장점은 다음과 같습니다:

  • 코드 구조화: 논리적으로 관련된 클래스를 하나의 클래스 내부에 묶어 관리할 수 있습니다.
  • 캡슐화 강화: 외부 클래스와 관련된 기능을 내부 클래스에 정의하여 외부로 노출하지 않으면서도 기능을 구현할 수 있습니다.
  • 외부 클래스와의 긴밀한 관계: 내부 클래스는 외부 클래스의 멤버에 쉽게 접근할 수 있습니다.

2. 내부 클래스의 종류

자바에서 내부 클래스는 네 가지 주요 유형으로 나뉩니다:

  1. 인스턴스 내부 클래스(Non-static Inner Class)
  2. 정적 내부 클래스(Static Nested Class)
  3. 로컬 클래스(Local Class)
  4. 익명 클래스(Anonymous Class)

2.1 인스턴스 내부 클래스 (Non-static Inner Class)

인스턴스 내부 클래스는 외부 클래스의 인스턴스에 종속된 클래스로, 외부 클래스의 인스턴스가 생성된 이후에만 내부 클래스를 사용할 수 있습니다. 내부 클래스는 외부 클래스의 모든 인스턴스 변수와 메서드에 접근할 수 있습니다.

인스턴스 내부 클래스 예제

class OuterClass {
    private String outerField = "Outer Class Field";

    // 인스턴스 내부 클래스
    class InnerClass {
        public void display() {
            // 외부 클래스의 멤버에 접근 가능
            System.out.println("Accessing: " + outerField);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // 외부 클래스의 인스턴스 생성
        OuterClass outer = new OuterClass();

        // 내부 클래스의 인스턴스 생성
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.display(); // 출력: Accessing: Outer Class Field
    }
}

결과:

Accessing: Outer Class Field

위 예제에서 InnerClassOuterClass의 인스턴스 내부 클래스이며, 외부 클래스의 인스턴스 outer를 통해 내부 클래스 객체를 생성하고, 외부 클래스의 필드에 접근할 수 있습니다.

2.2 정적 내부 클래스 (Static Nested Class)

정적 내부 클래스는 외부 클래스의 인스턴스와 독립적입니다. 따라서 외부 클래스의 인스턴스를 생성하지 않고도 정적 내부 클래스의 객체를 생성할 수 있으며, 정적 내부 클래스는 외부 클래스의 정적(static) 멤버에만 접근할 수 있습니다.

정적 내부 클래스 예제

class OuterClass {
    private static String staticField = "Static Field";

    // 정적 내부 클래스
    static class StaticNestedClass {
        public void display() {
            // 외부 클래스의 정적 멤버에 접근 가능
            System.out.println("Accessing: " + staticField);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // 정적 내부 클래스의 인스턴스 생성
        OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
        nested.display(); // 출력: Accessing: Static Field
    }
}

결과:

Accessing: Static Field

위 예제에서 StaticNestedClassOuterClass의 정적 내부 클래스입니다. 정적 멤버는 외부 클래스의 인스턴스 없이도 사용할 수 있으며, 외부 클래스의 정적 필드에 접근할 수 있습니다.

2.3 로컬 클래스 (Local Class)

  • *로컬 클래스(Local Class)**는 메서드나 블록 내에 선언된 클래스로, 해당 메서드 내에서만 사용할 수 있습니다. 로컬 클래스는 메서드 내의 로컬 변수에 접근할 수 있지만, 접근하려는 변수는 반드시 final이거나 effectively final이어야 합니다.

로컬 클래스 예제

class OuterClass {
    public void printMessage() {
        final String message = "Hello from Local Class!";

        // 메서드 내에 로컬 클래스 선언
        class LocalClass {
            public void display() {
                // 로컬 클래스에서 메서드의 로컬 변수에 접근 가능
                System.out.println(message);
            }
        }

        // 로컬 클래스의 인스턴스 생성 및 메서드 호출
        LocalClass local = new LocalClass();
        local.display();
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.printMessage();  // 출력: Hello from Local Class!
    }
}

결과:

Hello from Local Class!

위 예제에서 로컬 클래스 LocalClass는 메서드 printMessage() 내부에서 선언되었습니다. 이 클래스는 메서드 내의 로컬 변수인 message에 접근할 수 있습니다.

2.4 익명 클래스 (Anonymous Class)

  • *익명 클래스(Anonymous Class)**는 이름이 없는 클래스이며, 클래스 정의와 동시에 인스턴스를 생성하는 방식입니다. 주로 인터페이스나 추상 클래스를 구현할 때 사용되며, 한 번만 사용되는 일회성 클래스를 정의할 때 유용합니다.

익명 클래스 예제

interface Greeting {
    void sayHello();
}

public class Main {
    public static void main(String[] args) {
        // 익명 클래스를 사용하여 Greeting 인터페이스 구현
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello() {
                System.out.println("Hello from Anonymous Class!");
            }
        };

        greeting.sayHello();  // 출력: Hello from Anonymous Class!
    }
}

결과:

Hello from Anonymous Class!

위 예제에서 Greeting 인터페이스를 구현하는 익명 클래스가 생성되었습니다. 익명 클래스는 new 키워드와 함께 바로 인스턴스를 생성하며, 클래스의 이름이 필요 없을 때 유용합니다.

내부 클래스의 장점

1. 캡슐화 강화

내부 클래스는 외부 클래스와 논리적으로 연관된 작업을 그룹화하여 코드의 가독성을 높이고, 외부로부터 세부 구현을 숨길 수 있어 캡슐화를 강화합니다.

2. 코드의 논리적 구조화

내부 클래스는 외부 클래스와 긴밀한 관계를 맺기 때문에, 외부 클래스와 관련된 작업을 하나의 단위로 묶을 수 있습니다. 이를 통해 코드의 구조화를 용이하게 하고, 관련성이 없는 클래스들을 서로 분리할 수 있습니다.

3. 외부 클래스 멤버에 쉽게 접근

내부 클래스는 외부 클래스의 멤버(필드, 메서드)에 쉽게 접근할 수 있습니다. 이를 통해 외부 클래스와의 협력 작업을 효율적으로 수행할 수 있습니다.

내부 클래스의 단점

1. 복잡성 증가

내부 클래스는 외부 클래스와 밀접한 관계를 맺기 때문에, 너무 많은 내부 클래스를 사용하면 코드가 복잡해질 수 있습니다.

2. 테스트 어려움

내부 클래스는 외부 클래스와 밀접하게 결합되어 있으므로, 독립적으로 테스트하기 어렵습니다.

요약

  • *내부 클래스(Inner Class)**는 외부 클래스의 내부에 정의된 클래스로, 외부 클래스와 긴밀한 관계를 가지며 외부 클래스의 멤버에 쉽게 접근할 수 있습니다.
  • 자바에서 내부 클래스는 네 가지로 나뉩니다: 인스턴스 내부 클래스, 정적 내부 클래스, 로컬 클래스, 익명 클래스.
  • 내부 클래스는 코드의 구조화와 캡슐화를 강화하고, 외부 클래스와의 상호작용을 쉽게 해주지만, 복잡성을 증가시킬 수 있습니다.

내부 클래스는 외부 클래스와 관련된 기능을 내부적으로 처리할 때 유용하며, 특히 자바 GUI 프로그램이나 이벤트 처리 시스템에서 자주 사용됩니다.


copyright ⓒ 스타트코딩 all rights reserved.
이메일 : startcodingim@gamil.com