Stay Hungry Stay Foolish

자바/자바 중급

[자바 중급] 07. 중첩 클래스, 내부 클래스 1

dev스카이 2024. 10. 9. 20:51

중첩 클래스, 내부 클래스

클래스 안에 클래스를 중첩해서 정의할 수 있는데, 이것을 중첩 클래스(Nested Class)라 한다.

class Outer {
     ...
     //중첩 클래스
     class Nested {
     	...
     }
}

 

 

중첩 클래스 종류

중첩 클래스는 총 4가지가 있고, 크게 2가지로 분류할 수 있다. 중첩 클래스의 의미는 정적과 내부 클래스를 모두 포함한 것을 말하며, 정적 중첩 클래스는 말 그대로 정적 중첩 클래스를 의미한다. 내부 클래스는 내부, 지역, 익명 클래스를 포함한 것을 말한다.

  • 정적 중첩 클래스 
  • 내부 클래스 종류
    • 내부 클래스 : 바깥 클래스의 인스턴스의 멤버에 접근
    • 지역 클래스 : 내부 클래스의 특징 + 지역 변수에 접근
    • 익명 클래스 : 지역 클래스의 특징 + 클래스의 이름이 없는 특별한 클래스

 

변수의 선언 위치

  • 정적 변수(클래스 변수)
  • 인스턴스 변수
  • 지역 변수

중첩 클래스의 선언 위치

  • 정적 중첩 클래스 ➜  정적 변수와 같은 위치
  • 내부 클래스 ➜  인스턴스 변수와 같은 위치
  • 지역 클래스 ➜  지역 변수와 같은 위치

 

변수의 선언 위치와 중첩 클래스의 선언 위치는 아래 코드와 같이 보면 이해하기 쉽다.

class Outer {
     ...
     //정적 중첩 클래스
     static class StaticNested {
     	...
     }
     
     //내부 클래스
     class Inner {
     	...
     }
     
     public void process() {
     //지역 변수
     int lcoalVar = 0;
     
     //지역 클래스
     class Local {...}
     
     Local local = new Local();
     }
}

 

 

🌟 정리

정리하면 정적 중첩 클래스는 바깥 클래스의 안에 있지만 바깥 클래스와 관계 없는 전혀 다른 클래스를 말한다. 내부 클래스는 바깥 클래스의 내부에 있으면서 바깥 클래스를 구성하는 요소를 말한다. 핵심은 바깥 클래스 입장에서 볼 때 안에 있는 클래스가 나의 인스턴스에 소속이 되는가 되지 않는가의 차이이다. 정적 중첩 클래스는 바깥 클래스와 전혀 다른 클래스이므로 바깥 클래스의 인스턴스에 소속되지 않는다. 반면에 내부 클래스는 바깥 클래스를 구성하는 요소이므로, 바깥 클래스의 인스턴스에 소속된다.

 

중첩 클래스는 특정 클래스가 다른 하나의 클래스 안에서만 사용되거나, 둘이 아주 긴밀하게 연결되어 있는 특별한 경우에만 사용해야 한다. 중첩 클래스를 사용하는 이유는 논리적 그룹화와 캡슐화 때문이다.

 

 

정적 중첩 클래스 특징

public class NestedOuter {
    static class Nested {
        ...
    }
}

 

  • static이 붙는다.
  • 바깥 클래스의 인스턴스에 소속되지 않는다.
  • 자신의 멤버에 접근할 수 있다.
    • 정적 중첩 클래스에서 선언한 멤버 변수에 접근 가능
  • 바깥 클래스의 인스턴스 멤버에는 접근할 수 없다.
    • 바깥 클래스에서 선언한 인스턴스 멤버는 접근 불가능(static이 붙지 않음)
    • 예시) private int outInstanceValue = 2;
  • 바깥 클래스의 클래스 멤버에는 접근할 수 있다. 같은 클래스 안에 있을 때 private도 접근 가능하다.
    • 바깥 클래스에서 선언한 클래스 멤버는 접근 가능(static이 붙음)
    • 예시) private static int outClassValue = 3;

 

메인에서 중첩 클래스에 접근하려고 할 때

public class NestedOuterMain {
 	public static void main(String[] args) {
 	NestedOuter.Nested nested = new NestedOuter.Nested();
    }
}

 

  • 바깥 클래스.정적중첩클래스 객체명 = new 바깥클래스.정적중첩클래스()
  • new NestedOuter() 로 만든 바깥 클래스의 인스턴스와 new NestedOuter.Nested() 로 만든 정적 중첩 클래스의 인스턴스는 서로 아무 관계가 없는 인스턴스이다. 따라서 바깥 클래스의 인스턴스는 생성하지 않아도 된다.

 

내부 클래스의 특징

public class InnerOuter {
 	class Inner {
            ...
    }
}

 

  • static이 붙지 않는다.
  • 바깥 클래스의 인스턴스에 소속된다.
  • 자신의 멤버에는 접근할 수 있다.
    • 내부 클래스에 선언한 멤버 변수에 접근 가능
  • 바깥 클래스의 인스턴스 멤버에 접근할 수 있다.  같은 클래스 안에 있을 때 private도 접근 가능하다.
    • 내부 클래스에서 바깥 클래스에 선언한 인스턴스 멤버에 접근 가능
    • 예시) private static int outClassValue = 3;
  • 바깥 클래스의 클래스 멤버에 접근할 수 있다.  같은 클래스 안에 있을 때 private도 접근 가능하다.
    • 내부 클래스에서 바깥 클래스에 선언한 클래스 멤버에 접근 가능
    • 예시) private int outInstanceValue = 2;

 

메인에서 내부 클래스에 접근하려고 할 때

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

 

  • 바깥 클래스.내부클래스 객체명 = 바깥 클래스 인스턴스.new 내부클래스()
  • 내부 클래스는 바깥 클래스의 인스턴스에 소속되어야 한다. 따라서 내부 클래스를 생성할 때, 바깥 클래스의 인스턴스 참조가 필요하다.