오늘은 자바기초를 끝내고 oop 기초에 들어섰다.
객체가 어떠한 건지 설명을 들었고,
class와 instance에 대한 설명을 붕어빵 틀과 붕어빵에 비유했었다.
붕어빵 틀이 class고, 붕어빵이 instance인 셈
그리고 class를 구성하고 있는 것을 member라 하고,
member 중 상태를 field라 하며, 기능을 method라 한다.
붕어빵에서 색이나 내용물의 종류를 field라 할 수 있고,
붕어빵에 대한 기능은 없으니 method는 없다.
그리고 혼자 공부하던 와중에
중첩 클래스(Nested Class)에 대해 처음 들어보아서
집중적으로 파보았고, 오늘은 이 중첩 클래스에 대해 이야기 하고자 한다.
위 붕어빵은 일반적인 붕어빵과 달리 특징이 하나 더 있다.
아이스크림이 있다는 것
이 아이스크림의 맛, 토핑 등을 정할 수 있다면,
붕어빵을 만들 때 손님에게 붕어빵의 종류,
아이스크림 맛에 대해 주문을 받아야 한다.
그래서 아이스크림에 대한 class는 붕어빵 틀 속에 있으며,
이 때 아이스크림 class를 중첩 class라고 한다.
중첩 class 는 다시 inner class와 static class로 나뉠수 있다.
(사실 익명 class 하나가 더 있지만, 후에 알아보자)
내부 class는 외부 class의 instance를 생성하고난 뒤,
따로 내부 class를 생성해 줘야 사용이 가능하다.
class Outer{
...
class Inner{
...
}
}
class static void main(String[] args){
// 외부 클래스 instance화
Outer outerClass = new Outer();
// 내부 클래스 instance화
Outer.Inner innerClass = outerClass.new Inner();
}
내부 class 또한 외부 class에 속하므로,
외부 class의 private뿐만 아니라 protected한 member에 접근이 가능하다.
또한, 섀도잉(Shadowing)이라고 Overriding이랑 비슷한 개념이 있는데,
class Outer{
private int i = 0;
class Inner{
private int i = 1;
}
}
이렇게 같은 변수명으로 field i가 내외부 class에 정의 되더라도,
오류 없이 실행이 가능하며,
위 경우 내부 class에서 i를 print할 때 1이 출력할 것이다.
만약 내부 class에서 외부 class의 i에 접근 하려면,
Outer.this.a
위와 같이 접근할 수 있다.
내부 class에서 하나 불가능한 것이 있다.
바로 static member 정의다.
itelliJ에서 내부 class안에 static member를 선언하려 했을 때,
어긋났다는 표시인 빨간 밑줄과 함께 원인을 알려주었다.
Static declarations in inner classes are not surpported at language level '11'
- java 11버전은 내부 class에서 Static 선언을 지원하지 않는다.
(java 16부터는 내부 class에서 static member 선언이 가능하다고 하다.)
여기서 또 왜 안되는지 궁금해졌는데,
구글링과 GPT의 결과를 요약해 보았다.
내부 class를 instance화 할때 마다 static member를
(field의 경우 같은 값이어도) 각각 따로
메모리에 할당하기 때문에 메모리 낭비가 발생 할 수 있고,
내부 class의 static member와 외부 class의 instance는
서로 독립적인 존재가 되버리며,
외부 class의 static member를 사용할 때 마다
외부 class instance를 생성해야 되기 때문에
내부 클래스의 재사용성과 유지 보수성을 저하시킨다.
static inner class(이하static class)는
외부 class instance의 member에 접근이 불가능하다.
print() 부분을 보면, static field인 m3외에
다른 field는 접근이 불가능하다.
static class를 instance화 할 때,
외부 class를 instance화 할 필요가 없기 때문이다.
아래는 static class의 instance화 과정이다.
class Outer{
...
static class Inner{
...
}
}
class static void main(String[] args){
// 내부 class instance화
Outer.Inner innerClass = new Outer.Inner();
}
Inner class와의 차이를 잘 알아보길..
GPT에 따르면,
Inner class는
사용되고
static class는
사용된다고 한다.
두 중첩 class의 특징이나 차이에 대해선 잘 알겠는데,
아직 사용처에 대해선 이해가 잘 안간다.
또한, 구글링 결과
중요한 사실을 알았는데,
inner class는 static class보다 안좋다는 사실을 알았다.
출처
위 출처는 꼭 한번 들어가서 읽어보길 권장한다.
사용처에 대해 이해가 안갔기도 했고,
inner class가 안좋다는 얘기도 들었기에
당분간은 static class만 사용하려 한다.