[이것이자바다] chapter 9. 중첩 클래스와 중첩 인터페이스 (inner class , inner interface) 3
chapter 9
중첩 클래스와 중첩 인터페이스
UI클래스 예시 및 익명 객체의 로컬 변수 사용
UI 클래스 : 익명 구현 객체 사용 사례
버튼 클래스
package UI;
public class Button {
OnClickListener listener;
void setOnClickListener(OnClickListener listener){ //매개변수의 다형성
this.listener = listener;
}
void touch(){ //인스턴스 메소드
listener.onClick();
}
interface OnClickListener{ // 중첩 인터페이스
void onClick(); // 중첩 인터페이스의 추상 메소드
}
}
윈도우 클래스
package UI;
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("홈페이지를 끕니다.");
}
});
}
}
메인 함수 실행(WindowExample)
package UI;
public class WindowExample {
public static void main(String[] args) {
Window window = new Window();
window.button1.touch();
window.button2.touch();
}
}
익명 객체의 로컬 변수 사용
- 익명 객체 내부에서는 바깥 클래스의 필드나 메소드는 제한없이 사용할 수 있다. 문제는 메소드의 매개변수나 로컬 변수를 익명 객체에서 사용할 때이다. 메소드 내에서 생성된 익명 객체는 메소드 실행이 끝나도 힙 메모리에 존재해 계속 사용할 수 있지만 , 메소드의 매개변수나 로컬 변수는 메소드가 종료되면 소멸되므로(스택에 있다) 익명 객체에서 사용할 수 없어서 문제가 발생하게 된다.
- 해결로는 로컬 인터페이스의 내부에 매개변수나 로컬 변수의 값을 복사해 사용하는 것이다. 이때 매개 변수나 로컬변수가 값이 변경되어 로컬 인터페이스에 복사해 둔 값과 달라지는 문제를 해결하기 위해 매개 변수나 로컬변수를 final로 선언하여 문제를 막는다.
- 자바 8부터는 메소드의 매개변수나 로컬변수를 굳이 final로 선언하지 않아도 final의 특성을 지니고 있기 때문에 걱정하지 말자.
인터페이스 Calculatable
package Nested;
public interface Calculatable {
int sub();
}
메소드안에 로컬 인터페이스가 있는 클래스 Anonymous
package Nested;
public class Anonymous {
private int field = 0;
public int method(int arg1, int arg2){
field =10;// 필드이므로 로컬 클래스에서 사용해도 값 변경 가능
int var1 = 0;
int var2 =0;
// arg1 =10; 로컬 클래스에서 사용하므로 값 변경 불가능
//arg2 = 10; 로컬 클래스에서 사용하므로 값 변경 불가능
//var1 =5; 로컬 클래스에서 사용하므로 값 변경 불가능
//var2 = 5; 로컬 클래스에서 사용하므로 값 변경 불가능
Calculatable calc = new Calculatable() {
@Override
public int sub() {
return arg1 - arg2 - field - var1 - var2;
}
};
return calc.sub();
}
}
메인 메소드
package Nested;
public class AnonymousExample {
public static void main(String[] args) {
Anonymous anonymous = new Anonymous();
//메소드 사용
int result = anonymous.method(20,0);
System.out.println(result);
}
}
=> 실행 결과:
10