ch09. 중첩 클래스와 중첩 인터페이스
09-1. 중첩 클래스와 중첩 인터페이스
➡️인스턴스 멤버 : 객체 생성없이 사용 불가능한 멤버 ( 객체마다 소속되는 멤버)
➡️정적 멤버 : 객체 생성없이도 사용 가능한 멤버 ( 클래스에 고정된 멤버) , 클래스로 바로 접근해서 사용 O
[중첩 클래스] : Nested 네스티드 클래스
중첩 클래스 : 클래스 내부에 선언한 클래스
→ 클래스 내부에 에 따라
→ 선언된 위치에 따라
◾<멤버 클래스> : 바깥 클래스 블록 내부에 클래스의 멤버로서 선언된 중첩 클래스
: 바이트 코드 이름 : 바깥 $ 멤버.class
✅인스턴스 멤버 클래스
: 바깥 객체가 생성되어야만 생성해서 사용 가능한 멤버 클래스
: (static) 키워드 없이 선언된 멤버 클래스
: 클래스 내부에 인스턴스 필드와 메소드만 선언 가능
**<<객체 생성 방법>>**
바깥 클래스 외부에서 객체 생성 시, 바깥 객체 생성 후 -> 안쪽 객체 생성 가능
바깥 클래스 내부에서 객체 생성 시, 자기 객체 생성해서 사용
✅정적 멤버 클래스
: 바깥 객체 생성 없이도 클래스로 바로 접근해서 객체 생성 가능한 멤버 클래스
: (static) 키워드로 선언된 멤버 클래스
: 클래스 내부에 모든 종류의 필드,메소드 선언 가능
<<객체 생성 방법>>
바깥 클래스 외부에서 객체 생성 시, 바깥 객체 생성없이 바로 클래스로 접근해서 자기 객체 생성 O
✅로컬 클래스
[중첩 클래스의 접근 제한]
<바깥 클래스 필드.메소드에서// 멤버 클래스 객체 생성에 대한 제한>
바깥 인스턴스 필드, 메소드 ( 바깥 객체 생성해야만 사용 가능한 멤버)
→ 인스턴스 멤버 클래스의 객체 생성 O 사용 O
→ 정적 멤버 클래스의 객체 생성 O 사용 O
바깥 정적 필드, 메소드 (바깥 객체 생성 없이도 사용 가능한 멤버)
→ 정적 멤버 클래스의 객체 생성 O 사용 O
: 인스턴스 멤버 클래스는 바깥 객체 생성되어야만 사용 가능한 멤버 클래스이므로
객체 생성 없이도 사용 가능한 static 타입 멤버로는 객체 생성 불가능
<멤버 클래스 내부에서// 바깥 클래스 멤버에 접근 제한>
인스턴스 멤버 클래스 안에서 -> 바깥 클래스의 모든 필드.메소드 접근 O
정적 멤버 클래스 안에서 -> 바깥 클래스의 정적 필드.메소드에만 접근 O
: A 객체 생성 후 B 객체 생성되고, B 객체 생성되어야 B객체 내부 메소드 호출됨
: B 객체 내부에서는 A,B 객체의 멤버 모두 사용 O
: A 객체 생성 없이도 생성 가능한 C 객체는,
A 객체 생성되어야만 사용가능한 A의 인스턴스 멤버를 C객체 내부에서 사용 X
A 객체 생성 없이도 사용 가능한 A의 정적 멤버는 C 객체 내부에서 사용 O
<로컬 클래스 내부에서 //메소드의 매개변수와 로컬별수 사용 시 제한>
: 자바는 컴파일 시 로컬 클래스에서 사용하는 매개변수,로컬변수 값을 로컬 클래스 내부에 복사해두고 사용
: 따라서 해당 변수들에 final 특성 부여해서 사용
: final 특성 부여
= final 선언 안해도, 매개변수는 매개값 받은 그대로, 로컬 변수는 최초 초기화값 그래도 사용 가능
: 즉, 중간에 값 바꿀 수 없고 그대로 가져와서 로컬 클래스에서 사용 가능
<중첩 클래스 내부에서// 바깥 클래스를 참조> : 이름 동일한 필드,메소드 사용시
중첩 클래스 내부에서 객체 자신의 참조 : this.필드 / this.메소드
중첩 클래스 내부에서 바깥 클래스의 필드.메소드 접근
: 바깥클래스.this.필드 / 바깥클래스.this.메소드
[중첩 인터페이스] : Nested 네스티드 인터페이스
: 클래스의 멤버로 선언된 인터페이스
: 해당 클래스와 긴밀한 관계 맺는 구현 클래스 생성을 위해 중첩 인터페이스 선언
: 내부 UI 설계에서 이벤트 처리 시 多 사용
- 인스턴스 멤버 인터페이스 (바깥 클래스 객체 생성되어야만 사용O)
- 정적 멤버 인터페이스 (바깥 객체 생성 없이도, 바깥 클래스로 바로 접근해서 사용O)
: 주로 정적 멤버 인터페이스 사용 多
public class Button { //설계 UI 구현
static interface OnClickListener { //중첩 인터페이스 선언
void onClick();
}
OnClickListener listener; // Button클래스의 필드 : 인터페이스 타입으로 선언
void setOnClickListener (OnClickListener listener) { //Setter 메소드
this.listener = listener;
}
void touch() { //Button에 대한 touch() 이벤트 발생 시 호출될 메소드
listener.onClick();
}
< 설계 코드 해석>
Button 바깥 클래스에서 touch() 이벤트 발생 시 호출할 함수만 설계해둠
내부에 중첩 인터페이스 선언(내부 추상 메소드 선언)해두고, 매개값으로 구현 객체를 받도록
(인터페이스 타입으로 필드 선언 -> 인터페이스 타입 매개변수 Setter 메소드 호출해서 구현 객체를 매개값으로 받은 후, 인터페이스 타입 필드에 값 저장
→ touch() 메소드 실행 시. 필드에 저장된 구현 객체의 onClick() 메소드 호출 )
touch() 이벤트 발생 시 실행될 구체적인 내용은 구현 객체로 실행
09-2. 익명 객체
[익명 객체]
: 이름이 없는 객체
: 부모 객체를 상속받은 or 인터페이스를 구현한 // 익명 객체만 존재
: 명시적으로 클래스 이름을 사용하는 이유 ; 재사용성 높이기 위함(어디서든 객체 생성 가능)
: 재사용되지 않고 오직 특정 위치에서만 사용될 경우 익명 객체로 사용
[익명 자식 객체]
**부모타입 변수 = new 부모클래스 (매개값) { ... } ;**
// 해당 부모클래스를 상속받은 자식 클래스의 내용을 { }; 와 같이 작성 후,
new 연산자로 익명의 자식 객체 생성하여 // 부모타입 변수에 대입한다.
(1) 필드 선언 시 : 부모타입 필드 = 익명 자식 객체 대입
(2) 메소드 내 로컬 변수 선언 시 : 부모타입 로컬 변수 = 익명 자식 객체 대입
(3) 매개변수가 부모타입인 메소드 호출 시 : 부모타입 매개변수 = 익명 자식 객체 매개값으로 대입 후 호출
[익명 구현 객체 생성]
: 구현 클래스가 재사용되지 않고, 오로지 특정 위치에서 사용될 경우 익명 구현 객체 사용
인터페이스타입 변수 = new 인터페이스() { ... } ;
//해당 인터페이스를 구현한 클래스 내부에 {}; 내용을 작성한 뒤 new연산자로 구현 객체 생성하여 인터페이스 타입 변수에 대입
(1) 필드 선언 시 //
인터페이스 타입 필드 변수에 익명 구현 객체 초기값으로 대입
(2) 메소드 내에서 로컬변수 선언 시 //
인터페이스 타입 로컬 변수에 익명 구현 객체 대입
(3) 매개변수가 인터페이스 타입 변수로 선언된 메소드 호출 시 //
인터페이스 타입 매개변수에 매개값으로 익명 구현 객체 대입하여 호출
[익명 객체 내부에서 // 매개변수, 로컬변수 사용 시 제한]
: 자바는 컴파일 시 익명 객체에서 사용하는 매개변수, 로컬변수를 익명 객체 내부에 복사해두고 사용
: 컴파일러는 변수에 final특성 부여해서 값이 중간에 수정불가하도록 처리
: 매개값 받은 그대로, 초기값 선언된 그대로 각 변수를 익명 객체 내부에서 사용됨
: 중간에 값 변경 시 컴파일 에러
<<익명 구현 객체 이용한 UI 클래스>>
[UI 버튼 클래스]
public class Button {
OnClickListener listener;
void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
void touch() {
listener.onClick();
}
static interface OnClickListener {
void onClick();
}
}
[익명 객체 연결한 Window 클래스]
public class Window {
Button button1 = new Button();
Button button2 = new Button();
//필드 초기값으로 대입
Button.OnClickListener listener = new Button.OnClickListener() {
@Override
public void onClick() {
System.out.println("전화를 겁니다.");
Window() {
button1.setOnClickListener(listener);
//매개값으로 대입
button2.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick() {
System.out.println("메시지를 보냅니다.");
[실행 Main클래스]
public class Main {
public static void main(String[] args) {
Window w = new Window();
w.button1.touch();
w.button2.touch();
}
}
<<중첩 인터페이스 사용한 UI클래스>>
[중첩인터페이스 포함한 Button UI 클래스]
public class Button {
OnClickListener listener;
void setOnClickListener(OnClickListener listener) {
this.listener = listener;
}
void touch() {
listener.onClick();
}
static interface OnClickListener {
void onClick();
}
}
[구현 클래스 작성-1]
public class CallListener implements Button.OnClickListener {
@Override
public void onClick() {
System.out.println("전화를 겁니다.");
}
}
[구현 클래스 작성-2]
public class MessageListener implements Button.OnClickListener {
@Override
public void onClick() {
System.out.println("메시지를 보냅니다.");
}
}
[실행 Main클래스]
'Java > [문법]_Java(자바)' 카테고리의 다른 글
11-1. java.lang 패키지 (0) | 2021.08.11 |
---|---|
ch10. 예외 처리 (0) | 2021.08.05 |
ch08. 인터페이스 (0) | 2021.08.04 |
ch07. 상속 (0) | 2021.08.03 |
ch06. 클래스 (0) | 2021.08.02 |