객체는 이름이 없는 객체를 말한다.
명시적으로 클래스를 선언하지 않기 때문에 쉽게 객체를 생성할 수 있다는 장점이 있다. 익명 객체는 필드값, 로컬 변수값, 매개변수값으로 주로 사용이 된다.
익명 객체를 사용할 때 주의할 점은 클래스를 상속하거나 인터페이스를 구현해야만 생성할 수 있다.
익명 객체는 두 가지로 분류된다.
new 부모생성자(매가값,```){
//필드
//메소드
}
이때 부모 생성자 옆에 중괄호가 붙어있는데, 이 중괄호는 클래스의 선언부와 똑같다. 즉, 중괄호 블록 안의 필드와 메소드는 익명 자식 객체가 가져야할 멤버로 주로 부모 메서드를 재정의 하는 코드가 온다.
아래의 예제를 통해 알아보면,
먼저, Tire 의 클래스를 아래와 같이 생성을 한다.
그리고, Tire을 참조하기 위한 Car 클래스를 아래와 같이 생성한다.
public class Car {
// 필드에 Tire 객체 대입
private Tire tire1 = new Tire();
// 필드에 익명 자식 객체 대입
private Tire tire2 = new Tire(){
@Override
public void roll() {
System.out.println("익명 자식 Tire 객체 1이 굴러갑니다.");
}
};
public void run1(){
tire1.roll();
tire2.roll();
}
//메소드(로컬 변수 이용)
public void run2(){
Tire tire = new Tire(){
@Override
public void roll(){
System.out.println("익명 자식 Tire 객체 2가 굴러갑니다.");
}
};
tire.roll();
}
public void run3(Tire tire){
tire.roll();
}
}
CarExample 이라는 클래스를 생성해서 Car를 상속받는 car 객체를 생성한 후에 메소드를 호출하여 실행해본다.
public class CarExample {
public static void main(String[] args) {
//Car 객체 생성
Car car = new Car();
//익명 자식 객체가 대입된 필드 사용
car.run1();
//익명 자식 객체가 대입된 로컬변수 사용
car.run2();
//익명 자식 객체가 대입된 매개변수 사용
car.run3(new Tire(){
@Override
public void roll(){
System.out.println("익명 자식 Tire 객체 3이 굴러갑니다.");
}
});
}
}
결과는 아래와 같다
2,3,4 줄에서는 익명 자식 객체에서 재정의된 메서드 내용으로 호출됨을 알 수 있다. 즉, 다형성의 특징을 알아볼 수 있었다.
익명 구현 객체는 인터페이스를 구현한 이름 없는 객체로 정의된다.
new 인터페이스(){
//필드
//메소드
}
익명 구현 객체의 사용을 예제를 통해 알아보자
먼저 RemoteControl 이라는 이름의 인터페이스를 생성 후 아래의 코드를 입력한다.
public interface RemoteControl {
void turnOn();
void turnOff();
}
그 다음, Home이라는 이름의 클래스를 생성한다.
첫 번째 rc는 필드에서 RemoteControl 인터페이스를 구현하여 생성되었다.
두 번째 rc는 메소드 내의 지역변수에서 RemoteControl 인터페이스를 구현하여 생성되었다.
세 번째 rc는 메소드의 매개변수를 통해 구현한 RemoteControl을 입력받아 생성된다.
public class Home {
private RemoteControl rc = new RemoteControl() {
@Override
public void turnOn() {
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff() {
System.out.println("TV를 끕니다.");
}
};
public void use1(){
rc.turnOn();
rc.turnOff();
}
public void use2(){
RemoteControl rc = new RemoteControl() {
@Override
public void turnOn() {
System.out.println("에어컨을 켭니다.");
}
@Override
public void turnOff() {
System.out.println("에어컨을 끕니다");
}
};
rc.turnOn();
rc.turnOff();
}
public void use3(RemoteControl rc){
rc.turnOn();
rc.turnOff();
}
}
위 use 메서드를 실행하기 위해 HomeExample 이름의 클래스를 생성하고 아래와 같이 작성한다.
public class HomeExample {
public static void main(String[] args) {
Home home = new Home();
home.use1();
home.use2();
home.use3(new RemoteControl() {
@Override
public void turnOn() {
System.out.println("난방을 켭니다");
}
@Override
public void turnOff() {
System.out.println("난방을 끕니다.");
}
});
}
}
위 코드의 출력 결과는 다음과 같다.