내부 클래스(inner class)
내부 클래스는 주로 AWT나 Swing과 같은 GUI 어플리케이션의 이벤트 처리 외에는 잘 사용하지 않을 정도로 사용 빈도가 높지 않다. 그래도 기본 원리와 특징을 이해하는 정도까지는 학습을 해야한다.
내부 클래스란?
내부 클래스는 클래스 내에 선언된 클래스이다. 클래스에 다른 클래스를 선언하는 이유는 간단하다. 두 클래스가 서로 긴밀한 관계에 있기 때문이다.
한 클래스를 다른 클래스의 내부 클래스로 선언하면 두 클래스의 멤버들 간에 서로 쉽게 접근할 수 있다는 장점과 외부에는 불필요한 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다는 장점을 얻을 수 있다.
내부 클래스의 장점
- 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.
- 코드의 복잡성을 줄일 수 있다(캡슐화).
class Outer { // 외부 클래스
...
class Inner { // 내부 클래스
...
}
...
}
내부 클래스의 종류와 특징
내부 클래스의 종류는 변수의 선언 위치에 따른 종류와 같다. 내부 클래스는 마치 변수를 선언하는 것과 같은 위치에 선언할 수 있으며, 변수의 선언 위치에 따라 인스턴스변수,클래스변수,지역변수로 구분되는 것과 같이 내부 클래스도 선언 위치에 따라 아래와 같이 구분되어 있다.
내부 클래스 | 특징 |
인스턴스 클래스 (instance class) |
외부 클래스의 멤버변수 선언위치에 선언, 외부 클래스의 인스턴스 멤버처럼 다루어진다. 주로 외부 클래스의 인스턴스멤버들과 관련된 작업에 사용될 목적으로 선언된다. |
스태틱 클래스 (static class) |
외부 클래스의 멤버변수 선언위치에 선언, 외부 클래스의 static 멤버처럼 다루어진다. 주로 외부 클래스의 static 멤버, 특히 static 메서드에서 사용될 목적으로 선언된다. |
지역 클래스 (local class) |
외부 클래스의 메서드나 초기화블럭 안에 선언하며, 선언된 영역 내부에서만 사용될 수 있다. |
익명 클래스 (anonymous class) |
클래스의 선언과 객체의 생성을 동시에 하는 이름없는 클래스(일회용) 생성자 선언X, 오로지 단 하나의 클래스나 단 하나의 인터페이스를 상속받거나 구현할 수 있을 뿐 |
내부 클래스의 선언
클래스 멤버 변수도 선언되는 위치나 접근제어자에 따라 역할과 이름이 달라지듯이, 내부 클래스도 선언된 위치, static 키워드 사용 여부 등에 따라 구분된다.
class Outer{
class InstanceInner { ... } // 인스턴스 클래스
static class StaticInner { ... } // 스태틱 클래스
void myMethod(){
class LocalInner { ... } // 지역 클래스
}
Object o = new Object() { // 익명클래스
@Override
public String toString() {
return "toString 변경하기";
}
};
}
내부 클래스의 제어자와 접근성
위의 코드에서 인스턴스 클래스와 스태틱 클래스는 외부 클래스의 멤버변수와 같은 위치에 선언되고, 또한 멤버변수와 같은 성질을 갖는다.
즉, 내부 클래스가 외부 클래스의 멤버와 같이 간주되고, 인스턴스 멤버와 static 멤버간의 규칙이 내부 클래스에도 똑같이 적용된다.
그리고 내부 클래스도 클래스이기 때문에 abstract나 final과 같은 제어자를 사용할 수 있을 뿐만 아니라, 멤버 변수들처럼 private, protected과 접근제어자도 사용이 가능하다.
Class Inner{
class instanceInner{
int iv = 100;
//static int cv = 100; // 에러! static 변수 선언X
final static int CV = 100; // final static은 상수이므로 허용된다.
}
static class staticInner{
int iv = 200;
static int cv = 200; // static 클래스만 static 멤버를 정의할 수 있다.
}
void MyInner(){
class LocalInner{
int iv = 300;
//static int cv = 300; // 에러! static 변수 선언X
final static int CV = 300; // final static은 상수이므로 허용된다.
}
}
public static void main(String args[]){
System.out.println(instanceInner.CV); // 100 출력
System.out.println(staticInner.cv); // 200 출력
}
}
정리하자면 내부 클래스 중에서 스태틱 클래스만 static멤버를 가질 수 있다. 하지만 final static은 상수이므로 모든 내부 클래스에서 정의가 가능하다.
class Inner2{
class InstanceInner{}
static class StaticInner{}
// 인스턴스 멤버 간에는 서로 직접 접근이 가능!
InstanceInner iv = new InstatnceInner();
// static 멤버 간에는 서로 직접 접근이 가능!
StaticInner cv = new StaticInner();
static void staticMethod(){
// static 멤버는 인스턴스 멤버에 직접 접근할 수 없다.
// InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// 꼭 접근해야한다면 아래와 같이 객체를 생성해야함
Inner2 in = new Inner2();
InstanceInner obj1 = in.new InstanceInner();
}
void instanceMethod(){
// 인스턴스 메서드에서는 인스턴스 멤버와 static 멤버 모두 접근 가능
InstatnceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
// 메서드 내에 지역적으로 선언된 내부클래스는 외부에서 접근X
LocalInner lv = new LocalInner();
}
void myMethod(){
class LocalInner{}
LocalInner lv = new LocalInner();
}
}
인스턴스멤버는 같은 클래스에 있는 인스턴스멤버와 static 멤버 모두 직접 호출이 가능하지만 static멤버는 인스턴스 멤버를 직접 호출할 수 없다.
인스턴스클래스는 외부 클래스의 인스턴스 멤버를 객체 생성 없이 바로 사용할 수 있지만, 스태틱 클래스는 외부 클래스의 인스턴스 멤버를 객체생성 없이 사용할 수 없다.
이와 마찬가지로 인스턴스 클래스는 스태틱 클래스의 멤버들을 객체생성 없이 사용할 수 있지만, 스태틱 클래스에서는 인스턴스 클래스의 멤버들을 객체생성 없이 사용할 수 없다.
#참고자료
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
'개발 > JAVA' 카테고리의 다른 글
[JAVA] 예외(Exception)와 에러(Error) (0) | 2023.03.23 |
---|---|
[JAVA] 익명 클래스(Anonymous class) (0) | 2023.03.23 |
[JAVA] 인터페이스(Interface) vs 추상클래스(Abstract Class) 비교 (0) | 2023.03.06 |
[JAVA] 인터페이스(Interface) 총 정리 (0) | 2023.03.01 |
[JAVA] 추상클래스(Abstract Class) 총 정리 (0) | 2023.02.27 |