[JAVA] 내부 클래스

2024. 9. 2. 19:10·Back-End/Java

[작성일: 2023. 02. 01]

 

 

내부 클래스(inner class)

  • 클래스 안의 클래스
  • 내부 클래스에서 외부 클래스의 멤버들을 객체생성 없이 쉽게 접근할 수 있음.
  • 코드의 복잡성을 줄일 수 있음.(캡슐화)
  • 내부 클래스의 종류와 유효범위(scope)는 변수와 동일함.(iv, cv, lv)
class A { // B 클래스의 외부 클래스
  int i = 100;
  B b = new B();
   
  class B { // A 클래스의 내부 클래스
    void method() {
      System.out.println(i); // 객체 생성없이 외부 클래스의 멤버 접근 가능
    }
  }
}

// class C {
//  B b = new B(); // 사용 불가
//  }


public class InnerTest {
  public static void main(Strint[] args) {
  }
}

 

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

 

 

 

 

 

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

  • 내부 클래스의 제어자는 변수에 사용 가능한 제어자와 동일함.
  • 내부 클래스의 접근 제어자는 default와 public 뿐만 아니라, private, protected도 가능함.
  • static 멤버를 가질 수 있는 건 static 클래스뿐이므로 주의해서 작성할 것
  • 외부 클래스의 객체를 먼저 생성해야 내부 클래스의 객체 생성이 가능해짐.
class Ex7 {

  class InstanceInner {
    int iv = 100; 
    static int cv = 100;    // 에러! static 변수 선언 불가능
    final static int CONST = 100;    // final static은 상수이므로 허용함.
  }

  static class StaticInner {
    int iv = 200;
    static int cv = 200;   // static 클래스만 static 멤버 정의 가능.
  }

  void myMethod() {
    class LocalInner {
      int iv = 300;
      static int cv = 300;    // 에러! static 변수 선언 불가능
      final static int CONST = 300;    // final static은 상수이므로 허용함.
    } 
      int i = LocaliNNER.const; // ok
  }
  
  public static void main(String[] args) {
    System.out.println(InstanceInner.CONST); // 가능
    System.out.println(StaticInner.cv); // 가능
 // System.out.println(LocalInner.CONST); 
 // 에러! 지역 내부 클래스는 메서드 내에서만 사용 가능함.
}
class Ex7_2 {
  class InstacneInner {}
  static class StaticInner {}
  
  InstanceInner iv = new instanceInner(); // 인스턴스 멤버끼리는 접근 가능
  static Staticinner cv = new StaticInner(); // static 멤버끼리는 접근 가능
  
  static void staticMethod() { // static 멤버는 인스턴스 멤버에 직접 접근 불가능
 // InstanceInner obj1 = new InstanceInner();
    StaticInner obj2 = new StaticInner(); 
  }
  
  void instanceMethod() { // 인스턴스 메서드에서는 인스턴스 멤버와 static 멤버 모두 접근 가능
    InstanceInner obj1 = new InstanceInner();
    StaticInner obj2 = new StaticInner(); 
 // LocalInner lv = new LocalInner(); // 지역 내부 클래스는 외부에서 접근 불가능
  }
  
  void myMethod() {
    class LocalInner {}
    LocalInner lv = new LocalInner(); // 내부에서만 사용 가능
  }
}
class Outer {
  private int outerIv = 0;
  static int outerCv = 0;
  
  class InstanceInner {
    int iiv = outerIv; // 외부 클래스의 private 멤버 접근 가능
    int iiv2 = outerCv;
  }
  
  static class StaticInner {
    int siv = outerIv; // static 클래스는 외부 클래스의 인스턴스 멤버에 접근 불가능
    static int scv = outerCv; // 외부 클래스의 static 맴버 접근 가능
  }
  
  void myMethod() {
    int lv = 0; // 메서드 종료와 함께 지역변수는 소멸됨.
    final int LV = 0; // JDK1.8부터 final 생략 가능
    
    class LocalInner {
      int liv = outerIv;  
      int liv2 = outerCv;
   // 외부 클래스의 지역변수는 final이 붙은 변수(상수)만 접근 가능함.
      int liv3 = lv;  // JDK1.8부터 값이 안 바뀌면 상수로 취급하기 때문에 에러 없음.
      int liv4 = lV;  // OK
    }
  }
}
class Outer2 {
  class InstanceInner {
    int iv = 100;
  }
  static class StaticInner {
    int iv = 200;
    static int cv = 300;
  }
  
  void myMethod() {
    class LoclaInner { 
      int iv = 400;
    }
  }
}

class Ex7_3 {
  public static void main(String[] args) {
    Outer2 oc = new Outer2(); // 외부 클래스의 객체를 먼저 생성해야 내부 클래스 객체 생성 가능
    Outer2.InstanceInner ii = oc.new InstanceInner();
    
    System.out.println("ii.iv);
    System.out.println("Outer2.StaticInner.cv); 
    
    // static 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 됨.
    Outer2.StaticInner si = new Outer2.StaticInner();
    // 앞에 외부 클래스 이름 붙여줘야 함.
    System.out.println(si.iv);
  }
}
class Outer3 {
  int value = 10; // Outer3.this.value, 외부 클래스의 iv
  
  class Inner {
    int valuee = 20;  // this.value , 내부 클래스의 iv
    
    void method1() {
      int value = 30; // lv
      System.out.println(value); // 가까운 value 출력 -> lv
      System.out.println(this.value);
      System.out.println(Outer3.this.value);
    }
  }
}

class Ex7_4 {
  public static void main(String[] args) {
    Outer3 outer = new Outer3();
    Outer3.Inner inner = outer.new Inner();
    inner.method1();
  }
}


// 결과
30
20
10

 

 

 

 

 

익명 클래스(anonymous class)

  • 이름이 없는 일회용 클래스(조상의 이름 사용)
  • 클래스의 정의와 생성을 동시에 함.
new 조상클래스이름() { // ex) new Ojbect() {}
  // 멤버 선언
  // 클래스의 내용
}

  또는
  
new 구현인터페이스이름() {
  // 멤버 선언
}


//Java의   AWT에서 자주 사용함.

import java.awt.*;

class 7_5 {
  public static void main(String[] args) {
    Button b = new Button("Start");
    b.addActionListener(new ActionListener() { 
    // 클래스의 정의와 객체 생성을 동시에 함. 조상의 이름 사용.
      public void actionPerformed(ActionEvent e) {
        System.out.println("ActionEvent Occurred!");
      }
    }
  }
}

 

 

 

 

 

 

 

 

 

 


🐣 해당 게시글은 자바의 정석(남궁성 님) 영상으로 함께 공부하며 요약/정리한 글입니다.
🐣 입문 개발자가 작성한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.

 

저작자표시 비영리 변경금지 (새창열림)
'Back-End/Java' 카테고리의 다른 글
  • [JAVA] java.lang패키지의 유용한 클래스
  • [JAVA] Object 클래스
  • [JAVA] 예외처리
  • [JAVA] 객체지향 - 디폴트 메서드, static 메서드
뚜비
뚜비
1년차 백엔드&iOS 개발자의 감자 탈출 블로그 🥔🥔
  • 뚜비
    뚜비의 개발로그
    뚜비
  • 전체
    오늘
    어제
  • 글쓰기     관리
    • Devlog
      • Back-End
        • Java
        • Spring
        • JPA
        • HTTP
        • Security
        • Back-End
        • Front-End
      • 알고리즘
      • iOS
        • Swift
      • Database
      • Tips
        • Git & GitHub
        • A to Z
      • 프로젝트
      • 생각정리
  • 태그

    의존성주입
    Swift
    javascript
    jsp
    sql
    spring
    Database
    자바
    JPA
    게시판만들기
    다형성
    객체
    성능최적화
    김영한
    DB
    html
    최주호
    생성자
    데이터베이스
    프로그래머스
    알고리즘
    MVC
    HTTP
    스프링
    Security
    백준
    자바스크립트
    Java
    Spring Security
    변수
  • hELLO· Designed By정상우.v4.10.0
뚜비
[JAVA] 내부 클래스
상단으로

티스토리툴바