티스토리 뷰
중첩 클래스
- 두 클래스의 맴버들을 서로 쉽게 접근 할 수 있음
- 외부에는 불필요한 관계 클래스를 감춤으로써 코드의 복잡성 감소
ex) class ClassName {
class NestedClassName {
}
}
1. 멤버 클래스 : 클래스의 멤버로써 선언되는 중첩 클래스
- 클래스나 객체가 사용중이라면 언제든지 재사용 가능
ex) class A {
class B { }
}
2. 로컬 클래스 : 메소드 내부에서 선언되는 중첩 클래스
- 메소드 실행 시에만 사용
- 메소드 실행 종료시 사라짐
ex) class A {
static class B { }
}
- 인스턴스 멤버 클래스 : static 키워드 없이 선언된 클래스
- 인스턴스 필드와 메소드만 선언 가능
- 정적 필드와 메소드는 선언 불가
- A 클래스 외부에서 인스턴스 멤버 클래스 B의 객체를 생성하려면 먼저 객체를 생성하고 B 객체를 생성해야함
- 정적 멤버 클래스 : static 키워드로 선언된 클래스
- 모든 종류의 필드와 메소드 선언 가능
- A 클래스 외부에서 정적 멤버 클래스 B의 객체를 생성하기 위해서는 A 객체를 생성할 필요가 없다
- 로컬 클래스 : 메소드 내에서 선언한 중첩 클래스
- 접근 제한자(public, private) 및 static을 붙힐 수 없음 -> 메소드 내부에서만 사용되기 떄문
- 인스턴스 필드와 메소드만 선언가능
- 정적 필드와 메소드는 선언할 수 없음
//바깥 클래스
class A{
A() {System.out.println("A 객체 생성됨");}
//인스턴스 멤버 클래스
class B{
B() {System.out.println("B 객체가 생성됨");}
int field1;
//static int field2;
void method1() { }
//static void method2() { }
}
//정적 멤버 클래스
static class C{
C(){System.out.println("C 객체가 생성됨");}
int field1;
static int field2;
void method1() { }
static void method2() { }
}
void method() {
//로컬 클래스
class D{
D(){System.out.println("D 객체가 생성됨");}
int field1;
//static int field2;
void method1() { }
//static void method2() { }
}
D d = new D();
d.field1 = 3;
d.method1();
}
}
public class Main{
public static void main(String[] args) {
A a = new A();
//인스턴스 멤버 클래스 객체 생성
A.B b = a.new B();
b.field1 = 3;
b.method1();
//정적 멤버 클래스 객체 생성
A.C c = new A.C();
c.field1 = 3;
c.method1();
A.C.field2 = 3;
A.C.method2();
//로컬 클래스 객체 생성을 위한 메소드 호출
a.method();
}
}
중첩 클래스의 접근 제한
- 바깥 필드와 메소드에서 사용 제한
public class A{
//인스턴스 필드
B field1 = new B();
C field2 = new C();
//인스턴스 메소드
void method1() {
B var1 = new B();
C var2 = new C();
}
//정적 필드 초기화
//static B field3 = new B();
static C field4 = new C();
//정적 메소드
static void method2() {
//B var1 = new B();
C var2 = new C();
}
//인스턴스 멤버 클래스
class B { }
//정적 멤버 클래스
static class C { }
}
- 멤버 클래스에서 사용 제한
public class A{
int field1;
void method1() { }
static int field2;
static void method2() { }
class B {
void method() { //모든 필드와 메소드에 접근 가능
field1 = 10;
method1();
field2 = 10;
method2();
}
}
static class C{
void method() {
//인스턴스 필드와 메소드는 접근 불가
//field1 = 10;
//method1();
field2 = 10;
method2();
}
}
}
- 로컬 클래스에서 사용제한
- 로컬 클래스에서 사용 가능한 것은 final로 선언된 매개 변수와 로컬 변수뿐
- final 키워드가 있다면 로컬 클래스의 메소드 내부에 지역 변수로 복사
- final 키워드가 없다면 로컬 클래스의 필드로 복사
#자바 8 이후부터는 final 키워드를 붙히지 않아도 final 특성을 갖고 있음!
public class Outter {
public void method(int arg) {
int localVariable = 1;
//arg = 100; //(x)
//localVariable = 100; //(x)
class Inner{
public void method() {
int result = arg + localVariable;
}
}
}
}
- 중첩 클래스에서 바깥 클래스 참조 얻기
- this 키워드를 사용하면 중첩 클래스의 객체가 참조됨
- 중첩 클래스 내부에서 바깥 클래스의 객체 참조를 얻으려면 바깥 클래스의 이름을 this앞에 붙혀주면 됨
public class Outter {
String field = "Outter-field";
void method() {
System.out.println("Outter-method");
}
class Nested{
String field = "Nested-field";
void method() {
System.out.println("Nested-Method");
}
void print() {
//중첩 객체 참조
System.out.println(this.field);
this.method();
//바깥 객체 참조
System.out.println(Outter.this.field);
Outter.this.method();
}
}
}
//실행 클래스
public class OutterEx{
public static void main(String[] args) {
Outter outter = new Outter();
Outter.Nested nested = outter.new Nested();
nested.print();
}
}
'LANGUAGE > JAVA' 카테고리의 다른 글
[JAVA] 삼항연산자 (0) | 2019.07.12 |
---|---|
[JAVA] ANONYMOUS OBJECT - 익명 객체 (0) | 2018.06.28 |
[JAVA] ECLIPSE 단축키 (0) | 2018.04.15 |
[JAVA] 경로 (0) | 2018.04.15 |
[JAVA] INSTANCEOF (0) | 2018.04.15 |