[Java] 내부 클래스(inner class)
본문 바로가기
Java

[Java] 내부 클래스(inner class)

by IYK2h 2022. 12. 26.
728x90

이 글은 https://youtu.be/CXuA31XcBZ0 를 통해 개념 정리 후 복습용으로 정리한 글입니다.

문제시 바로 삭제하겠습니다.


 

내부 클래스(inner class)

  • 클래스 안의 클래스
class A { // 외부 클래스
  ...
    classB { // 내부 클래스
    ... // 객체 생성 없이도 A의 멤버 접근 가능
  }
}

내부 클래스의 장점

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

내부 클래스의 종류와 특징

  • 내부 클래스의 종류와 유효범위(scope)는 변수와 동일
내부클래스 종류 특징
인스턴스 클래스 iv (instance class) 외부클래스의 멤버변수 선언위치에 선언하며, 외부클래스의 인스턴스처럼 다뤄진다. 주로 외부클래스의 인스턴스 멤버들과 관련된 작업에 사용될 목적으로 선언된다.
스태틱 클래스 cv (static class) 외부클래스의 멤버변수 선언위치에 선언하며, 외부클래스의 static멤버처럼 다루어진다. 주로 외부클래스의 static멤버, 특히 static 메소드에서 사용될 목적으로 선언된다.
지역 클래스 lv (local class) 외부클래스의 메소드에 선언하며, 선언된 영역 내부에서만 사용될 수 있다
익명 클래스 (anonymous class) 클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용)

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

  • 내부 클래스의 제어자는 변수에 사용 가능한 제어자와 동일
  • static 내부 클래스만 static멤버를 정의할 수 있다.
    • static멤버는 객체생성 없이 사용 가능하기 때문
  • 외부 클래스의 private멤버도 내부 클래스에서 접근가능하다.
  • 지역 내부 클래스를 감싸고 있는 메서드의 상수만 사용 가능
//예제.01
class OutClass {
  class InstanceInner {
    int iv = 100;
    static int cv = 100; // 에러!! static변수를 선언할 수 없다. static 내부 클래스만 가능
    final static int Const = 100; // final static은 상수이므로 허용
  }

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

  void myMethod() {
    class LocalInner {
      int iv = 100;
      static int cv = 100; // 에러!! static변수를 선언할 수 없다. static 내부 클래스만 가능
      final static int Const = 100; // final static은 상수이므로 허용
    } 
  }
}

public static void main(String args[]) {
  System.out.println(InstanceInner.Const);
  System.out.println(StaticInner.cv);
  System.out.println(LocalInner.cv); //에러. 지역 내부 클래스는 메서드 내에서만 가능
}
//예제.02
class OutClass {
  class InstanceInner {}
  static class StaticInner {}

  InstanceInner iv = new InstanceInner();         //인스턴스 멤버끼리는 직접 접근 가능
  static StaticInner cv = new StaticInner(); //Static 멤버끼리는 직접 접근 가능

  static void staticMethod() {
//      InstanceInner obj1 = new InstanceInner(); //static멤버는 인스턴스 멤버에 직접 접근 불가
    static StaticInner obj2 = new StaticInner();
  }

  void instanceMethod() { //인스턴스메서드에서는 인스턴스멤버와 static멤버 모두 접근 가능
    InstanceInner obj1 = new InstanceInner();
    static StaticInner obj2 = new StaticInner(); 
  }
}
//예제.03
class OutClass {
  private int outerIv = 0;
  static int outerCv = 0;

  class InstanceInner {
    int iv = outerIv; //외부 클래스의 private멤버도 접근가능하다.
    int iv2 = outerCv;
  }

  static class StaticInner {
//    int iv = outerIv; //static 클래스는 외부 클래스의 인스턴스 멤버에 직접 접근 불가
    int iv2 = outerCv;
  }

  void myMethod() {
    int Iv = 0; // 변수
    final int Lv = 0; // 상수 JDK1.8부터 final 생략 가능

    class LocalInner {
      int iv = outerIv; //외부 클래스의 private멤버도 접근가능하다.
        int iv2 = outerCv;
// 지역 내부 클래스를 감싸고 있는 메서드의 상수만 사용 가능
// 외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근 가능하다.
// 내부 클래스의 객체가 지역변수보다 더 오래 존재 가능하기 때문에 발생하는 에러
//      int iv3 = Iv; //에러. (JDK1.8부터 에러 아님)
      int iv4 = Lv;
    } 
  }
}
//예제.04
class OutClass {
  class InstanceInner { int iv = 100; }
  static class StaticInner { int iv = 200; static int cv = 300; }
  void myMethod() { class LocalInner { int iv = 400; } }
}

class ex04 {
  public static void main(String args[]) {
    Outer oc = new OutClass(); // 외부 클래스의 인스턴스를 먼저 생성해야 인스턴스 클래스의
    Outer.InstanceInner il = oc.new InstanceInner(); // 인스턴스를 생성 가능

    System.out.println("ii.iv = "+ii.iv); //100
    System.out.println("Outer.StaticInner.cv = "+Outer.StaticInner.cv); //300

    //스태틱 내부 클래스의 인스턴스는 외부 ㅁ클래스를 먼저 생성하지 않아도 된다
    Outer.StaticInner si = new Outer.StaticInner();
    System.out.println("si.iv = "+si.iv); //200
  }
}
//예제.05
class OutClass {
  int value = 10;

  class Inner { 
      int value = 20;

    void method() {
      int value = 30;
      System.out.println("value : "+ value); //30
      System.out.println("this.value : "+ this.value); //20
      System.out.println("Outer.this.value : "+ Outer.this.value); //10
    }
  } //Inner클래스의 끝
} //Outer클래스의 끝
728x90

댓글