포스트

[JAVA] 내부 클래스(Inner Class) 장점과 종류

내부 클래스의 장점

캡슐화 향상

내부 클래스는 외부 클래스의 멤버로서, 외부 클래스와 밀접하게 관련된 기능을 제공한다.
이를 통해 외부 클래스의 구현 세부 사항을 감출 수 있으며, 외부 클래스의 캡슐화를 향상시킬 수 있다.

1
2
3
4
5
6
7
8
9
10
class Outer {
    private int data = 10;

    class Inner {
        void display() {
	        // 외부 클래스의 private 멤버에 접근 가능
            System.out.println("Data: " + data); 
        }
    }
}

코드의 논리적 그룹화

내부 클래스는 외부 클래스와 밀접하게 관련된 클래스를 하나의 논리적 단위로 그룹화할 수 있다.
코드의 구조를 명확하게 하고, 관련된 기능을 한 곳에 모아 작성할 수 있다.

1
2
3
4
5
6
7
8
9
class Graph {
    class Node {
        // Node와 관련된 기능
    }
    
    class Edge {
        // Edge와 관련된 기능
    }
}

내부 클래스 종류

내부 클래스특징
인스턴스 클래스
instance class
외부 클래스의 멤버변수 선언 위치에 선언하며, 외부 클래스의 인스턴스 멤버처럼 다뤄진다.
주로 외부 클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언된다.
스태틱 클래스
static class
외부 클래스의 멤버변수 선언 위치에 선언하며, 외부 클래스의 static 멤버처럼 다뤄진다.
외부 클래스의 static메소드로 사용될 목적으로 선언된다.
지역 클래스
local class
외부 클래스의 메서드나 초기화블럭 안에 선언하며, 선언된 메서드 블록 영역 내부에서만 사용될 수 있다.
익명 클래스
anonymous class
클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스(일회용)

인스턴스 내부 클래스 (Instance Inner Class)

  • 인스턴스 내부 클래스는 외부 클래스의 인스턴스와 연관된 내부 클래스
  • 외부 클래스의 인스턴스 없이 생성될 수 없다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Outer {
    private String outerField = "외부필드";

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

    public static void main(String[] args) {
        Outer outer = new Outer(); // 외부 클래스 인스턴스 생성
        Outer.Inner inner = outer.new Inner(); // 인스턴스 내부 클래스 인스턴스 생성
        inner.display(); // 접근: 외부필드 출력
    }
}

정적 내부 클래스 (Static Inner Class)

  • 외부 클래스의 인스턴스와 독립적으로 존재가 가능하다.
  • 정적 멤버만 접근할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Outer {
    private static String staticOuterField = "정적외부필드";

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

    public static void main(String[] args) {
        Outer.Inner inner = new Outer.Inner(); // 정적 내부 클래스 인스턴스 생성
        inner.display(); // 접근: 정적외부필드 출력
    }
}

지역 내부 클래스 (Local Inner Class)

  • 지역 내부 클래스는 메서드나 초기화 블록 내에서 선언된다.
  • 해당 블록이 실행될 때만 생성되고 사용된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Outer {
    void outerMethod() {
        final String localVar = "지역 변수"; // 지역 변수는 final 또는 effectively final 이어야 함

        // 지역 내부 클래스
        class LocalInner {
            void display() {
                // 메서드 내의 지역 변수에 접근 가능
                System.out.println("접근: " + localVar);
            }
        }

        LocalInner localInner = new LocalInner(); // 지역 내부 클래스 인스턴스 생성
        localInner.display(); // 접근: 지역 변수 출력
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.outerMethod(); // 지역 내부 클래스 메서드 호출
    }
}

익명 내부 클래스 (Anonymous Inner Class)

  • 익명 내부 클래스는 이름이 없는 내부 클래스
  • 주로 일회성 사용을 위해 선언과 동시에 인스턴스를 생성하여 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import javax.swing.*;
import java.awt.event.*;

public class MyFrame extends JFrame {
    private JButton button;

    public MyFrame() {
        button = new JButton("클릭");

        // 익명 내부 클래스로 이벤트 핸들러 구현
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("버튼 클릭됨");
            }
        });

        add(button);
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args) {
        new MyFrame(); // JFrame을 상속받은 MyFrame 인스턴스 생성
    }
}

ActionListener 인터페이스를 구현한 익명 내부 클래스는 button.addActionListener 메서드 호출 시 바로 정의되고 인스턴스화된다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.