class A{
class B{ ... }
}
class A{
void method(){
class B(){ ... }
}
인스턴스 멤버 클래스(안쪽 클래스)를 사용하기 위해선, 안쪽 클래스는 인스턴스 멤버이므로 반드시 바깥 클래스 객체를 만들어야 사용 가능
안쪽 클래스에 대한 객체를 만들려면 바깥 클래스 객체가 만들어져야 함
class A{
class B{
B(){ }
int field1;
void method1();
// static int field2; => 정적 필드 선언불가능
// static void method2();
}
}
A a = new A(); // 안쪽 클래스 B 를 사용하기 위해 바깥 클래스 A 객체를 먼저 생성
A.B b = a.new B(); // 바깥 클래스의 객체 a 의 멤버인
// 안쪽 클래스 B의 생성자를 호출해서 안쪽 클래스 객체 b 를 생성
b.field1 = 3;
b.method1();
static 키워드로 선언된 멤버 클래스
static 멤버 클래스 안에 static 필드(변수) 와 메소드를 선언 가능
static 멤버는 객체 안만들고 사용 가능.
class A{
static class C{
int field1;
static int field2; // 정적 멤버 선언가능
void method1() { }
static void method2() { } // 정적 메소드 선언가능
}
}
A.C c = new A.C(); // 보듯이 바깥 클래스 객체 안 만들고 객체 생성가능하다.
c.field1 = 3;
c.method1();
A.C.field2 = 3;
A.C.method2();
예제
class A{
A() { System.out.println("A 객체 생성됨");
// 인스턴스 멤버 클래스 B
public class B{
B() { { System.out.println("B 객체 생성됨"):
int field1;
void method1() { }
}
// static 멤버 클래스 C
static class C{
C() { { System.out.println("C 객체가 생성됨"):
int field1;
static int field2;
void method1(){ };
static void method2() { }
}
// 로컬 클래스 D
void method(){
class D{
D() { { System.out.println("D 객체가 생성됨"):
int field1;
void method1() { }
}
D d = new D();
d.field1 = 3;
d.method1();
}
}
main 함수 내용
A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method1();
A.C c = new A.C(); // static 멤버 클래스의 객체는 바깥 클래스 객체 따로 안만들어도 생성 가능
c.field1 = 3;
c.method1();
A.C field2 = 3;
A.C.method2();
a.method();
static 은 static 만 사용할 수 있다는 개념을 다시 적용!
static 메소드에서는 static 멤버 클래스에 access (ex. static 멤버 클래스로 객체 만들기) 가 가능하지만, 일반 멤버 클래스에는 access 불가능
static 은 static 만 사용할 수 있다는 개념을 다시 적용!
static 멤버들은 static 멤버 클래스만 사용가능
하지만 그냥 인스턴스 멤버 클래스는 사용 불가능
반대로 static 멤버 클래스도 static 멤버에만 접근 가능
또한 그냥 인스턴스 멤버 클래스는 모든 멤버에 접근 가능!
public class A{
B field1 = new B();
C field2 = new C();
void method1(){
B var1 = new B();
C var2 = new C();
}
// 아래의 두개의 static 필드와 메소드는 클래스 C에만 접근 가능하다.
// 인스턴스 멤버 클래스, 필드, 메소드에는 접근 불가능!
static C field4 = new C(); // static 필드(변수)
static void method2(){ // static 메소드
C var2 = new C();
}
class B {} // 인스턴스 멤버 클래스
static class C {} // static 멤버 클래스
// 클래스 C는 field4, method2 에만 접근가능.
// 반면 클래스 B는 모든 멤버에 접근 가능
}
로컬 클래스
안쪽 클래스에서 this를 사용하면 안쪽 클래스에 대한 객체를 의미
바깥 클래스에 대해 this 를 사용하고 싶다면
바깥 클래스.this.멤버 형태로 사용할 것
원래는
부모클래스 변수명 = new 자식 클래스
인터페이스 변수명 = new 구현 클래스
이런 형태일떄 사용하는 것이지만, 자식 클래스와 구현 클래스의 이름이 말 그대로 "익명", 즉 이름이 없으므로 대신에
- 부모클래스 변수명 = new 부모 클래스 (){
(새롭게 선언할 내용)
(오버라이딩할 내용)
};
- 인터페이스 변수명 = new 인터페이스 () {
(새롭게 선언할 내용)
(오버라이딩할 내용)
};
형태로 선언해 사용하는 것이 익명객체이다.
즉, 이름이 없는 자식객체(구현객체) 를 생성후, 그 객체를 부모타입의 변수(인터페이스 변수) 에 갖다 붙이는 것이다.
ex)
parent p = new parent{
};
자식 클래스에 들어가는 내용이 모두 들어감
예제
익명 객체 내부에 새로 추가된 멤버들은 내부 연산에만 쓰일 수 있고, 외부에서 접근이 불가능함