[자바/심화] 내부 클래스(Inner Class)와 내부 인터페이스(Inner Interface)

내부 클래스 정의

- 다른 클래스의 내부에 존재하는 클래스를 의미하며, 또 다른 말로 중첩 클래스라고도 한다.

내부 클래스 특징

- 내부 클래스는 외부 클래스의 멤버에 자유롭게 접근할 수 있다.

- 외부에서는 내부 클래스에 접근이 불가능하다.

내부 클래스 종류

종류 특징
멤버 내부 클래스
( Instance Inner Class)
  외부 클래스의 멤버로 사용된다.
로컬 내부 클래스
(Local Inner Class)
  외부 클래스의 메소드 내에서 정의된다.
정적 내부 클래스
(Static Inner Class)
  static으로 지정된 내부 클래스이다.
익명 내부 클래스
(Anonymoous Inner Class)
  내부 클래스가 이름 없이 사용된다.

멤버 내부 클래스

정의

- 외부 클래스의 멤버처럼 정의된 클래스를 의미한다.

형식

class 외부클래스이름 {
    ...
    class 내부클래스이름 {
        ...
    }
}

인스턴스 생성 방법

외부클래스타입 참조변수1 = new 외부클래스 생성자();
외부클래스이름.내부클래스이름 참조변수2 = 참조변수1.new 내부클래스 생성자();

로컬 내부 클래스

정의

- 외부 클래스의 메서드 구현 블록에서 정의된 클래스를 의미한다.

- 메소드 호출 시 생성되어 작업 수행 후 메소드가 종료되면 메모리에서 삭제된다.

- 화면부에서 스레드 작업이 필요할 때 사용된다.

형식

class 외부클래스이름 {
    ...
    public void method1() {
        class 내부클래스이름 {
            ...
        }
        ...
    }
}

정적 내부 클래스

정의

- 내부 클래스가 static으로 지정된 클래스를 의미한다.

- 정적 내부 클래스는 정적 멤버와 인스턴스 멤버를 선언할 수 있다.

형식

class 외부클래스이름 {
    ...
    static 내부클래스이름 {
        ...
    }
    ...
}

접근 방법

- 프로그램 실행시 시 바로 메모리에 생성되므로, 외부클래스명.내부클래스명.멤버명으로 바로 접근할 수 있다.

- new 연산자를 이용해서 인스턴스 생성도 가능하다.

익명 내부 클래스

정의

- 이름을 가지지 않는 클래스를 의미한다.

- 익명 내부 클래스는 선언과 동시에 객체를 생성한다.

- 화면의 이벤트 핸들러와 같이 단발성 기능에 많이 사용되며, 일회용 클래스라고도 한다.

형식

클래스이름 참조변수이름 = new 클래스 이름() {
    ...
};

내부 클래스 예제

// 내부 클래스 구조
class Outer {
    public void print() {
        System.out.println("Outer.print");
    }
    
    class Inner {
        public void innerPrint() {
            Outer.this.print();
        }
    }
    
    static class InnerStaticClass {
        void innerPrint() {
            // Outer.this.print();    // static class에서는 static Method에 접근할 수 있음.
        }
    }
}

abstract class Person {
    public abstract void printInfo();
}

class Student extends Person {
    public void printInfo() {
        System.out.println("Student.printInfo");
    }
}

public class Main {
    public static void main(String[] args) {
    	
        // 외부 클래스
        Outer outer = new Outer();
        
        // 멤버 내부 클래스
        Outer.Inner inner = new Outer().new Inner();
        
        // 정적 내부 클래스
        Outer.InnerStaticClass innerStatic = new Outer.InnerStaticClass();
        
        // 익명 내부 클래스
        Person person = new Person() {
            @Override
            public void printInfo() {
                System.out.println("Main.printInfo");
            }
        };
    }
}

내부 인터페이스 정의

- 클래스의 멤버로 선언된 인터페이스를 의미한다.

- static 키워드로 지정할 수 있다.

- 주로 화면에서 이벤트를 처리하는 용도로 사용된다.

내부 인터페이스 예제

class Button {
    BottonEventListener listener;

    public void addBottonEventListener(BottonEventListener listener) {
        this.listener = listener;
    }

    // 버튼 클릭 시 인터페이스를 구현한 핸들러의 메서드 호출
    public void btnClicked(String btnName) {
        listener.btnClicked(btnName);
    }

    // 버튼 클릭 시 수행할 추상 메소드를 가지는 내부 인터페이스 선언
    static interface BottonEventListener {
        public void btnClicked(String btnName);
    }
}

class ButtonEventHandler implements Button.BottonEventListener {
    // 내부 인터페이스에 선언된 추상 메소드 구현
    @Override
    public void btnClicked(String btnName) {
        System.out.println(btnName + " 버튼을 클릭합니다.");
    }
}

public class Main {
    public static void main(String[] args) {
        Button button = new Button();
        button.addBottonEventListener(new ButtonEventHandler());

        button.btnClicked("등록");    // 등록 버튼을 클릭합니다.
        button.btnClicked("수정");    // 수정 버튼을 클릭합니다.
        button.btnClicked("삭제");    // 삭제 버튼을 클릭합니다.
    }
}

⊙ 참고 문헌

  1. 이병승, 「초보 개발자를 위한 자바:한 권으로 배우는 자바 마스터 가이드 북」, 영진닷컴, 2024, p564 - 575
  2. 마종현, 「제로베이스 백엔드 취업 파트타임 스쿨 5기:Part 01. Java 기초-Chapter 01. Java 프로그래밍-10.인터페이스」, 제로베이스, 2024, https://zero-base.co.kr/