class Outer {
static class StaticNested { //정적 중첩 클래스
...
}
class Inner { //내부 클래스
...
}
public void process() {
class Local {...} //지역 클래스
}
}
static
이 붙고 바깥 클래스의 인스턴스에 소속되지 않는다public class NestedOuter {
private static int outClassValue = 3;
private int outInstanceValue = 2;
static class Nested { // 정적중첩클래스
private int nestedInstanceValue = 1;
public void print() {
// 자신의 멤버에 접근
System.out.println(nestedInstanceValue);
// 바깥 클래스의 인스턴스 멤버에는 접근할 수 없다 -> 두개 클래스가 관계가 없으므로 인스턴스에 접근 불가능
//System.out.println(outInstanceValue);
// 바깥 클래스의 클래스(static) 멤버에는 접근할 수 있다. private도 접근 가능
System.out.println(NestedOuter.outClassValue);
}
}
}
// 위 코드 호출 (메인문)
// NestedOuter outer = new NestedOuter(); // 소속되어있지 않기 때문에 이 객체를 생성할 필요 없음
NestedOuter.Nested nested = new NestedOuter.Nested(); // new 바깥클래스.중첩클래스
nested.print(); // 1 3 출력
정적 중첩 클래스는 다른 클래스를 중첩해둔 것 뿐이며, 둘은 아무런 관계가 없다
쉽게 말해서 클래스 2개를 따로 만든것과 같다
그러므로 내부에 있는 객체만 생성해도됨
유일한 차이점은 private
접근 제어자에 접근할 수 있다는 것이다
class NestedOuter{
}
class Nested{
}
static
이 붙지 않고 바깥 클래스의 인스턴스에 소속된다public class InnerOuter {
private static int outClassValue = 3;
private int outInstanceValue = 2;
class Inner {
private int innerInstanceValue = 1;
public void print() {
// 자신의 멤버에 접근
System.out.println(innerInstanceValue);
// 외부 클래스의 인스턴스 멤버에 접근 가능, private도 접근 가능 -> 바깥 클래스의 인스턴스에 소속이므로
System.out.println(outInstanceValue);
// 외부 클래스의 클래스 멤버에는 접근 가능. private도 접근 가능
System.out.println(InnerOuter.outClassValue);
}
}
}
// 메인문
InnerOuter outer = new InnerOuter(); //바깥 클래스의 인스턴스를 생성해야 내부 클래스 객체를 생성 가능
InnerOuter.Inner inner = outer.new Inner();
inner.print()
public class LocalOuterV1 {
private int outInstanceVar = 3;
public void process(int paramVar) {
int localVar = 1;
class LocalPrinter {
int value = 0;
public void printData() {
System.out.println("value=" + value); // 0
System.out.println("localVar=" + localVar); // 1
System.out.println("paramVar=" + paramVar); // 2
System.out.println("outInstanceVar=" + outInstanceVar); // 3
}
}
LocalPrinter printer = new LocalPrinter();
printer.printData();
}
public static void main(String[] args) {
LocalOuterV1 localOuter = new LocalOuterV1();
localOuter.process(2);
}
}
-> 자신의 인스턴스 변수 접근 가능
-> 자신이 속한 코드 블럭의 지역변수 접근 가능
-> 자신이 속한 코드 블럭의 매개변수 접근 가능
-> 바깥 클래스의 인스턴스 멤버 접근 가능
💡 지역 클래스는 지역 변수처럼 접근 제어자
를 사용할 수 없음
Printer printer = new Printer(){ // 선언과 동시에 생성
int value = 0;
@Override
public void print(){
~~~
~~~
}
};
printer.print();
-> 익명클래스는 지역클래스 중 하나로, 클래스의 이름이 없다는 특징이 있음
-> 클래스 선언과 생성을 동시에 할 수 있음
-> 특정 부모 클래스(인터페이스)를 상속받고 바로 구현하는 경우 사용함
중첩클래스를 사용하는 이유 : 논리적 그룹화
, 캡슐화