익명 클래스...? 익명 객체...?
by mignon25람다식이 결국 익명객체라고 하는데 익명객체가 뭔지 모르겠다.
그래서 익명 객체에 대해서 먼저 정리해보았다.
익명 객체(익명 클래스)란?
이름이 없는 객체.
프로그램에서 일시적으로 한번만 사용되고 버려지는 객체.
익명 클래스를 사용해야 하는 상황?
- 프로그램 내에서 일시적으로(단발성으로) 한 번만 사용되어야 하는 객체일 경우
- UI 이벤트 처리, 스레드 객체 등 (단발성 이벤트 처리)
- 재사용성이 없고, 확장성을 활용하는 것이 오히려 유지보수에서 더 불리할 때.
- 비즈니스 로직이 정말 제각각이며, 재사용성이 전혀 없어 매번 클래스를 생성해야 하는 비용이 더 클 때
익명 객체 구현하기 (1) - 익명 자식 객체 생성
부모 / 자식 간 상속 아래 익명 자식 객체 생성
익명 자식객체를 생성은 3가지 방법으로 구현할 수 있다.
- 필드의 초기값
- 로컬변수의 초기값
- 매개변수의 매개값
// 곤충이라는 부모 클래스 가정
class Insect {
void attack() {
System.out.println("곤충은 공격을 한다.");
}
}
public class Anonymous {
// 👉🏻방법 1 : 필드에 익명 자식 객체 생성
Insect spider1 = new Insect() {
String name = "무당거미";
// 거미줄을 치다.
void cobweb() {
System.out.println(name + " : 사각형으로 거미줄을 친다.");
}
@Override
void attack() {
System.out.println(name + " : 독을 발사한다. ");
}
};
// 👉🏻 방법 2 : 로컬변수의 초기값으로 대입
void method1() {
Insect spider2 = new Insect() {
String name = "늑대거미";
// 거미줄을 치다
void cobweb() {
System.out.println(name + " : 육각형으로 거미줄을 친다.");
}
@Override
void attack() {
System.out.println(name + " : 앞니로 문다. ");
}
};
// 로컬변수이기 때문에 메서드에서 바로 사용
spider2.attack();
}
// 👉🏻방법 3 : 익명객체 매개변수로 대입
void method2(Insect spider) {
spider.attack();
}
// 실행 메서드
public static void main(String[] args) {
Anonymous a = new Anonymous();
// 방법 1 : 익명객체 필드 사용
a.spider1.attack();
// 방법 2 : 익명객체 로컬변수 사용
a.method1();
// 방법 3 : 매개변수로 익명객체 사용
a.method2(new Insect() {
String name = "타란튤라";
// 거미줄을 친다.
void cobweb() {
System.out.println(name + " : 그냥 마구잡이로 친다");
}
@Override
void attack() {
System.out.println(name + " : 공격 안하고 후퇴한다. ");
}
});
// 익명객체 내부에서 새롭게 정의된 필드, 메서드는 부모객체 타임의 참조변수로 접근 불가
a.spider1.name = "왕거미"; // 접근 불가 (익명객체에서 새롭게 정의한 필드)
a.spider1.cobweb(); // 접근 불가 (익명객체에서 새롭게 정의한 메서드)
a.spider1.attack(); // 접근 가능 (부모클래스 Insect 의 메서드 오버라이딩한 것)
}
}
익명 객체 구현하기 (2) - 익명 구현 객체
함수형 인터페이스를 구현한 객체 -> 람다식으로 표현할 수 있다.
익명 객체는 이벤트 UI에 많이 활용된다고 한다.
public class Button {
// 인터페이스 타입 필드
OnClickListener onClickListener;
// 중첩 인터페이스. => 버튼이 클릭되었을 때의 동작을 정의하는 메서드를 가지고 있다.
interface OnClickListener {
void onClick();
}
// 구현 객체의 onClick() 메서드 호출
void touch() {
onClickListener.onClick();
}
public OnClickListener getOnClickListener() {
return onClickListener;
}
// 필드멤버변수 onClickListener 에 대한 Setter
// 외부에서 해당 Setter 로 값을 지정하기 위해서는 매개변수로 내부 인터페이스 타입을 구현한 객체를 전달해야 한다.
// 그 내부 인터페이스는 추상메서드를 하나만 가지는 함수형 인터페이스이므로 => 람다식을 넣어서 전달할 수도 있다.
public void setOnClickListener(OnClickListener onClickListener) {
this.onClickListener = onClickListener;
}
}
class Test {
public static void main(String[] args) {
Button button = new Button();
// onClick() 의 동작 Setter 로 지정
button.setOnClickListener(() -> System.out.println("버튼 클릭!!!!"));
// 지정한 동작을 실행
button.touch(); // 버튼 클릭!!!!
Button startBtn = new Button();
Button endBtn = new Button();
// startBtn 과 endBtn 에 각각 다른 동작 지정
startBtn.setOnClickListener(() -> System.out.println("프로그램을 시작합니다!!"));
endBtn.setOnClickListener(() -> System.out.println("프로그램을 종료합니다!!"));
startBtn.touch(); // 프로그램을 시작합니다!!
endBtn.touch(); // 프로그램을 종료합니다!!
}
}
// 출력 결과
버튼 클릭!!!!
프로그램을 시작합니다!!
프로그램을 종료합니다!!
'Java' 카테고리의 다른 글
| Thread 생성 및 실행 (1) | 2023.03.10 |
|---|---|
| 메타 애너테이션(meta-annotation) (0) | 2023.03.08 |
| [Collection FrameWork] ArrayList, LinkedList (0) | 2023.03.08 |
| [Collection FrameWork] Collection, List, Iterator (Methods) (0) | 2023.03.07 |
| [Collection Framework] Map<K, V> (0) | 2023.03.06 |
블로그의 정보
Mignon'S Dev Log
mignon25