본문 바로가기
JAVA BASE/OOP(객체지향 프로그래밍)

13. [자바] 내부 클래스(inner class)

by staticClass 2020. 12. 20.

내부 클래스란?

내부 클래스는 클래스 안에 만들어진 클래스이다
이렇게 클래스 안에 클래스를 만드는 이유는 두 클래스가 서로 긴밀한 관계에 있기 때문이다.
클래스 안에 클래스를 만들게 되면 멤버들 간에 서로 쉽게 접근이 가능하고
불필요한 클래스를 감춰서 코드의 복잡성을 줄일 수 있다.

내부 클래스의 장점
 * 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
 * 코드의 복잡성을 줄일 수 있다(캡슐화)

 class A {    // 외부 클래스 (outer class)

     ...

     class B {  // 내부 클래스 (inner class)

         ...

     }
 }

⭐내부 클래스는 외부 클래스를 제외하고는 다른 클래스에서 잘 사용되지 않아야 한다.⭐

내부 클래스의 종류와 특징

내부 클래스의 종류는 변수의 선언위치에 따른 종류와 같다.
내부 클래스는 마치 변수를 선언하는 것과 같은 위치에 선언할 수 있으며, 변수의 선언위치에 따라
인스턴스변수, 클래스(static)변수, 지역변수로 구분되는 것과 같이
내부 클래스도 선언위치에 따라 다르게 구분된다.

내부 클래스 특    징
 인스턴스 클래스
 (instance class)
외부 클래스의 멤버변수 선언위치에 선언, 외부 클래스의 인스턴스멤버처럼 다루어진다.
주로 외부 클래스의 인스턴스멤버들과 관련된 작업에 사용될 목적으로 선언된다.
 스태틱 클래스
 (static class)
외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 static멤버처럼 다루어진다.
주로 외부 클래스의 static멤버, 특히 static메서드에서 사용될 목적으로 선언된다.
 지역 클래스
 (local class)
외부 클래스의 메서드나 초기화블럭 안에 선언하며, 선언된 영역 내부에서만 사용될 수 있다.
 익명 클래스
 (anonymous class)
클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용)
class Outer {
    class InstanceInner {        // 인스턴스 클래스
        static int cv = 100; ⬅ 에러, static 변수 선언 불가(static 클래스에만 선언가능)
    }
    static class StaticInner {  // 스태틱 클래스
        static int cv = 100;
    }

    void myMethod() {
        class LoacalInner {} // 지역 클래스
        AnonyClass c = new AnonyClass() {    // 익명 클래스
            // 멤버변수..
            // 초기화 블럭..
            // 생성자..
            // 메서드.. 모두 다 생성가능
        }
    }
}

내부 클래스의 제어자와 접근성

인스턴스클래스(InstanceInner)와 스태틱클래스(StaticInner)는
외부 클래스(Outer)의 멤버변수(인스턴스변수, 클래스변수)와 같은 위치에 선언되며,
멤버변수와 같은 성질을 갖는다. 따라서 내부 클래스가 외부 클래스의 멤버와 같이
간주되고, 인스턴스멤버와 static멤버 간의 규칙이 내부 클레스에도 똑같이 적용된다.

class Outer {
    private int iv = 0;
    protected static int cv = 0;

    void myMethod() {
        int iv = 0;
    }
}
    ↕  ↕  ↕  ↕  ↕  ↕
class Outer {
    private class InstanceInner {}
    protected static class StaticInner {}

    void myMethod() {
        class LocalInner {}
    }
}

내부 클래스도 클래스이기 때문에 abstract나 final 같은 제어자를 사용할 수 있고
멤버변수들처럼 private, protected과 접근제어자도 사용이 가능하다.

아래의 코드는 내부 클래스와 외부 클래스에 선언된 변수의 이름이 같을 때

변수 앞에 'this' 또는 '외부 클래스명.this'를 붙여서 서로 구별할 수 있다는 것을 보여준다.

또 내부 클래스 인스턴스 클래스의 인스턴스 생성방법과 static클래스의 생성방법에 대한 코드이다.

class Outer{

    int value = 10; // Outer.this.value

    class Inner {
        int value = 20 ; // this.value

        void method1() {
            int value = 30;
            System.out.println("           value" + value);
            System.out.println("      this.value" + this.value);
            System.out.println("Outer.this.value" + Outer.this.value);
        }
    }

    static class StaticInner {
        int iv = 200;
        static int cv = 300;
    }

}

public class InnerEx {
    public static void main(String[] args) {
        // 인스턴스클래스의 인스턴스를 생성하려면
        // 외부 클래스의 인스턴스를 먼저 생성해야 한다.
        Outer oc = new Outer();
        Outer.Inner ii = oc.new Inner();
        ii.method1();

        // 스태틱 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 된다.
        Outer.StaticInner si = new Outer.StaticInner();
    }
}

익명 클래스(anonymous class)

익명 클래스는 이름 그대로 익명! 이름이 없는 클래스이다.
선언과 객체의 생성을 동시에 하기 때문에 단 한번만 사용될 수 있고
오직 하나의 객체만을 생성할 수 있는 일회용 클래스이다.

public class Inner {
    Object iv = new Object() { void method(){} };       // 익명 메소드
    static Object cv = new Object() {void method(){} }; // 익명 메소드
	
    void myMethod() {
        Object lv = new Object() {void method(){} };    // 익명 메소드
    }
}

 

댓글