Ch7-45~50. 내부 클래스
0. 목차
Chapter7. 객체지향 프로그래밍Ⅱ
Ch7 - 45. 내부 클래스의 제어자와 접근성
Ch7 - 46. 내부 클래스의 제어자와 접근성 예제1
Ch7 - 47. 내부 클래스의 제어자와 접근성 예제2
Ch7 - 48. 내부 클래스의 제어자와 접근성 예제3
Ch7 - 49. 내부 클래스의 제어자와 접근성 예제4
Ch7 - 50. 내부 클래스의 제어자와 접근성 예제5
Ch7 - 45. 내부 클래스의 제어자와 접근성
▶ 클래스 앞 제어자
▷ 일반적 클래스 앞 제어자 : (default), public
2개만 가능
▷ 내부 클래스 앞 제어자 : (default), public, private, protected
4개 다 가능
▷ 내부 클래스 ≒ 변수
Ch7 - 46. 내부 클래스의 제어자와 접근성 예제1
▶ static 멤버를 가질 수 있는 건 static 클래스 뿐!
▷ staitc 멤버는 객체 생성없이 사용 가능한 것
▷ static 클래스는 객체 생성 안해도 됨
▷ iv → cv 사용 가능
▷ iv ← cv 사용 불가
class Outer {
class InstanceInner {
int iv = 100;
static int cv = 100; // ERROR! 인스턴스에서 static변수 → 선언 불가!
final static int CONST = 100; // final static = 상수 → 선언 가능
}
static class StaticInner {
int iv = 200;
static int cv = 200; // static에서 static변수 → 선언 가능
}
void method() {
class LocalInner {
int iv = 300;
static int cv = 300; // ERROR! Local에서 static변수 → 선언 불가!
final static int CONST = 300; // final static = 상수 → 선언 가능
}
}
}
▷ final static은 상수, 변수X → static 클래스 아니어도 사용 가능
▷ final static 상수는 객체 생성 없이 바로 호출도 가능
System.out.println(InstanceInner.CONST);
System.out.println(StaticInner.cv);
System.out.println(LocalInner.cv);
- 지역 내부 클래스는 method 안에서만 사용 가능!
Ch7 - 47. 내부 클래스의 제어자와 접근성 예제2
▶ static 메서드에서 instance 직접 사용 불가!
▷ iv → cv 사용 가능
▷ iv ← cv 사용 불가
▷ 같은 원리로 static에서 instance 직접 사용 불가!
class Outer {
class InstanceInner { }
static class StaticInner { }
InstanceInner iv = new InstanceInner();
static StaticInner cv = new StaticInner();
static void staticMethod() {
InstanceInner obj1 = new InstanceInner(); // ERROR! static 메서드 안에서 instance 직접 접근 불가
StaticInner obj2 = new StaticInner();
}
void instanceMethod() {
InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner(); // instance 메서드에서는 static 사용 가능
LocalInner lv = LocalInner(); // ERROR! 지역 내부 클래스는 메서드 안에서만
}
void method() {
class LocalInner {
LocalInner lv = new LocalInner();
}
}
}
Ch7 - 48. 내부 클래스의 제어자와 접근성 예제3
▶ 내부 클래스 private 사용 가능!
▷ private : 같은 클래스만 사용가능
▷ 내부 클래스 : 같은 클래스 안에 있는 다른 클래스
▷ 내부 클래스도 같은 클래스
class Outer {
private int outerIv = 0;
static int outerCv = 0;
class InstanceInner {
int iv = outerIv; // 외부 클래스의 private 사용 가능
int cv = outerCv;
}
static class StaticInner {
int siv = outerIv; // ERROR! static → 인스턴스 멤버 접근 불가
static int scv = outerCv;
}
}
▶ 지역 내부 클래스에서는 변수 사용 불가, 상수만 접근 가능
▷ 상수 : final int
▷ JDK1.8 부터는 final 생략가능
int lv = 0;
int LV = 0; // final int lv = 0;
- 겉보기에 똑같음
- 어떻게 구분?
- 값이 바뀌지 않으면 상수로 간주
▷ 상수만 접근 가능한 이유는 상수는 constant pool이란 곳에서 따로 관리
- method는 자기 할 거 다 하면 없어짐
- 근데 상수는 constant pool가면 있음
class Outer {
void method() {
int lv = 0;
final int LV = 0;
class LocalInner {
int iv = outerIv;
int cv = outerCv;
int lv = lv; // 원래는 ERROR! 외부 클래스 지역변수는 상수만 접근 가능, JDK1.8부터는 에러 아님
int lV = LV;
}
}
}
Ch7 - 49. 내부 클래스의 제어자와 접근성 예제4
▶ 인스턴스 사용하려면, 외부 클래스 인스턴스 먼저 생성!
▷ 인스턴스 사용하려면? 외부 클래스 인스턴스 생성 → 내부 클래스 인스턴스 생성
▷ static은? 외부 클래스 인스턴스 생성 안해도 됨, 바로 내부 클래스 인스턴스 생성
- 단, 생성 시
외부 클래스 이름.내부 클래스 이름 = new 외부 클래스 이름.내부 클래스 이름
class Outer {
class InstanceInner {
int iv = 100;
}
static class StaticInner {
int iv = 200;
static int cv = 300;
}
void method() {
class LocalInner {
int iv = 400;
}
}
}
class Test {
public static void main(String[] args) {
Outer o = new Outer(); // 외부 클래스의 인스턴스 먼저 생성
Outer.InstanceInner oi = o.new InstanceInner(); // 인스턴스 클래스의 인스턴스 생성 가능
Outer.StaticInner s = new Outer.StaticInner(); // static 내부 클래스는 외부 클래스 인스턴스를 먼저 생성 안해도 됨
}
}
Ch7 - 50. 내부 클래스의 제어자와 접근성 예제5
▶ 변수의 위치 파악
▷ 외부 클래스의 iv
▷ 내부 클래스의 iv
▷ lv
class Outer {
int value = 10; // 외부 클래스의 iv
class Inner {
int value = 20; // 내부 클래스의 iv
void method() {
int value = 30; // lv
System.out.println("value : " + value); // 가장 가까운 value
System.out.println("this.value : " + this.value); // 내부 클래스의 iv
System.out.println("Outer.this.value : " + Outer.this.value); // 외부 클래스의 iv
}
}
}
class Test {
public static void main(String[] args) {
Outer o = new Outer(); // 외부 클래스의 인스턴스 먼저 생성
Outer.Inner inner = o.new Inner(); // 인스턴스 클래스의 인스턴스 생성 가능
inner.method();
}
}
// console
value : 30
this.value : 20
Outer.this.value : 10