[이것이자바다] chapter 9. 중첩 클래스와 중첩 인터페이스 (inner class , inner interface) 2
chapter 9
중첩 클래스와 중첩 인터페이스
익명 객체
- 익명(anonymous) 객체는 이름이 없는 객체를 말한다.
- 익명 객체는 단독으로 생성할 수 없고 클래스를 상속하거나 인터페이스를 구현해야만 생성할 수 있다.
익명 자식 객체 생성
- 자식 클래스가 재사용되지 않고, 오로지 해당 필드와 변수의 초기값으로만 사용할 경우라면 익명 자식 객체를 생성해서 초기값으로 대입하는 것이 좋은 방법이다.
- 주의할 점은 하나의 실행문이므로 끝에는 세미콜론(;)을 반드시 붙여야한다.
- 익명 객체의 특징은 일회성이기 때문에 생성자를 선언할 수 없다는 것을 알고 있자.
class A{
Parent field = new Parent(){ //익명 자식 객체
int childField;
void childMethod(){}
@Override
void parentMethod(){} // 부모의 메소드를 오버라이딩
}; // 하나의 실행문이므로 끝에는 세미콜론(;)을 붙여야 한다.
}
- 익명 자식 객체에 새롭게 정의된 필드와 메소드는 익명 자식 객체 내부에서만 사용되고, 외부에서는 필드와 메소드에 접근할 수 없다.
- 왜냐하면 익명 자식 객체는 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용 할 수 있기 때문이다.
package Anonymous;
public class AnonymousExample {
public static void main(String[] args) {
Parent field = new Parent(){
int childField;
void childMethod(){
}
@Override
void parentMethod() {
System.out.println("부모 메소드");
}
@Override
void parentMethod(int childField) {
this.childField = childField;
System.out.println("부모 메소드: " + this.childField);
}
};
// 익명 객체만의 메소드로는 호출 불가능하고 ,
// 부모 클래스의 메소드를 호출해야 한다.
//((Parent) field).childField //호출 불가능
//((Parent) field).childMethod(); // 호출 불가능
field.parentMethod();
field.parentMethod(10);
}
}
=> 위의 코드는 필드 childField와 메소드 childMethod()는 parentMethod() 메소드 내에서 사용이 가능하나, A 클래스의 필드인 field로는 접근할 수 없다.
=> 외부에서 익명 자식 객체만의 필드와 메소드는 사용할 수 없고 부모 클래스의 필드와 메소드만 사용할 수 있다는 것을 명심하자.
익명 구현 객체 생성
- 구현 클래스가 재사용되지 않고, 오로지 해당 필드와 초기값으로만 사용하는 경우라면 익명 구현 객체를 초기값을 대입하는 것이 좋다.
- 추가적으로 필드와 메소드를 선언할 수 있지만, 실체 메소드에서만 사용이 가능하고 외부에서는 사용하지 못한다. (명심!)
익명 구현 객체 생성하는 방법
인터페이스 [필드|변수] = new 인터페이스(){
//인터페이스에 선언된 추상 메소드의 실체 메소드 선언
//필드
//메소드
}; //세미콜론은 반드시 붙여야 한다. 실행문이기에
익명 객체 사용 예
RemoteControl 인터페이스
package Anonymous;
public interface RemoteControl {
void turnOn();
void turnOff();
}
Anonymous 클래스
package Anonymous;
public class Anonymous2 {
//필드 초기값으로 대입
RemoteControl TV = new RemoteControl() {
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("TV를 끕니다.");
}
};
void method1(){
//로컬 변수값으로 대입
RemoteControl audio = new RemoteControl() {
@Override
public void turnOn() {
System.out.println("오디오를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("오디오를 끕니다.");
}
};
//로컬 변수 사용
audio.turnOn();
audio.turnOff();
}
void method2(RemoteControl remoteControl){
remoteControl.turnOn();
remoteControl.turnOff();
}
}
메인에서 Anoymous 클래스, 객체로 사용
package Anonymous;
public class Anoymous2Example {
public static void main(String[] args) {
Anonymous2 anonymous2 = new Anonymous2();
//익명 객체 필드 사용
anonymous2.TV.turnOn();
anonymous2.TV.turnOff();
//익명 객체 메소드 사용
anonymous2.method1();
//매개변수로 익명 객체 대입
anonymous2.method2(new RemoteControl() {
@Override
public void turnOn() {
System.out.println("자동차를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("자동차를 끕니다.");
}
});
}
}
=> 실행 결과:
TV를 켭니다.
TV를 끕니다.
오디오를 켭니다.
오디오를 끕니다.
자동차를 켭니다.
자동차를 끕니다.