[TIL] 20250108 중첩 클래스 1

Drumj·2025년 1월 8일
0

2025 TIL

목록 보기
9/11

중첩 클래스

중첩 클래스는 클래스 안에 정의한 클래스를 말한다.
이러한 중첩 클래스는 정의하는 위치에 따라 분류가 달라진다.

  • non-static
    • 내부 클래스 (inner)
    • 지역 클래스 (local) : 코드 블록에 선언
    • 익명 클래스 (anonymous) : 이름 없는 클래스
  • static : 정적 중첩 클래스

non-static 같은 경우는 바깥 인스턴스 소속이고
static은 전혀 다른 인스턴스라고 한다.

음... 이게 무슨말인지 알아보도록 하자.


정적 중첩 클래스

정적 중첩 클래스는 정적 변수와 같이 앞에 static 이 붙어있다.

public class Outer {
	private static int outClassValue = 3;
    private int outInstanceValue = 2;
    
    static class Nested {
    	private int value = 1;
        
        public void print() {
        	//자신의 멤버 접근
        	System.out.println(value);
            
            //바깥 클래스의 인스턴스 멤버 접근 불가
            //System.out.println(outInstanceValue);
            
            //바깥 클래스의 클래스 멤버 접근 가능, private 접근 가능
            System.out.println(outClassValue);
        }
    }
}

위의 예제 코드를 보면 Nested 클래스는 static으로 생성된 것을 볼 수 있다.

그리고 이 클래스는 자신의 멤버는 당연 접근할 수 있고 Outer 클래스의 outClassValue에도 접근할 수 있는 것을 볼 수 있다. static으로 생성된 변수이기 때문에 당연히 접근할 수 있다!
하지만 여기서 중요한 것은 private 접근제어자에도 접근할 수 있다는 것이다.

//생성
Outer outer = new Outer();
Outer.Nested nested = new Outer.Nested();

생성은 위와같이 new Outer 에서 바로 .Nested() 를 할 수 있다! 이게 static 중첩 클래스의 특징이다. outer 인스턴스를 거치지 않고 직접 만들 수 있는데...

사실 이런 정적 중첩 클래스 는 다른 클래스를 중첩해서 만든 것일 뿐이라고 한다.

class Outer{}

class Nested{}

이런 식으로 그냥 따로 만든 것과 같은데, 유일한 차이는 앞에서 말했듯이 같은 클래스에 만들었기 때문에 private 접근 할 수 있다는 점이라고 한다.

으으음.. 뭐 대강 이해는 했다

Outer.Nested nested = new Outer.Nested(); -> 이렇게 생성 가능하고
Outer 클래스의 private static 변수에 접근가능하다!


내부 클래스 Inner

내부 클래스는 앞서 알아본 정적 중첩 클래스와 달리 바깥 클래스의 인스턴스를 이루는 요소가 된다고 한다. 쉽게 얘기해서 내부 클래스는 바깥 클래스의 인스턴스에 소속 된다고...

이것도 바로 알아보자

public class Outer {
	private static int outClassValue = 3;
    private int outInstanceValue = 2;
    
    class Inner {
    	private int value = 1;
        
        public void print() {
        	//자신의 멤버에 접근
            System.out.println(value);
            
            //바깥 클래스의 인스턴스 멤버에 접근 가능. private 접근 가능
            System.out.println(outInstanceValue);
            
            //바깥 클래스의 클래스 멤버에 접근 가능. private 접근 가능
            System.out.println(outClassValue);
        }
    }
}

내부 클래스는 모든 멤버 변수에 접근이 가능하다. 왜??

//생성
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();

생성하는 것에서부터 차이가 좀 보인다. 여기서는 outer인스턴스를 거쳐서 내부 클래스를 생성하고 있다.

이렇게 먼저 Outer를 생성하고 Inner를 생성하기 때문에 인스턴스 변수에도 접근이 가능한 것!

이게 바로 내부 클래스는 바깥 클래스의 인스턴스에 소속된다는 뜻이다. 바깥 클래스의 인스턴스 참조가 필요하다는 뜻. 그래서 outer.new Inner(); 와 같은 방식으로 생성을 하는 것이고 Outer의 모든 멤버 변수에 접근이 가능하다.


언제 사용하는게 좋을까?

중첩 클래스는 특정 클래스Inner가 다른 하나의 클래스 안Outer에서만 사용되거나, 둘이 아주 긴밀하게 연결되어 있는 특별한 경우에만 사용해야 한다고 한다. 외부 여러곳에서 특정 클래스Inner를 사용한다면 중첩 클래스가 아닌 그냥 일반적으로 클래스로 생성해서 사용하는게 좋다.

그렇다면 이렇게 중첩 클래스를 사용하는 이유는 뭘까?

  • 논리적 그룹화 : 특정 클래스가 다른 하나의 클래스 안에서만 사용되는 경우 해당 클래스 안에 포함하는 것이 논리적으로 더 그룹화가 된다.
  • 캡슐화 : 중첩 클래스는 바깥 클래스의 private 멤버에 접근할 수 있다. 이렇게 해서 둘을 긴밀하게 연결하고 불필요한 public 메서드를 제거할 수 있다.

위와 같은 이유가 있다고 한다... 음.. 실제로 중첩 클래스를 많이 사용해보지 않아서 확 와닿지는 않는다. 예제를 더 많이 봐야겠다.


참조

  • 김영한의 실전 자바 - 중급 1편

0개의 댓글