Search
Duplicate

Java - 익명 클래스(Anonymous Class)

글감
Java
작성자
작성 일자
2024/02/08 06:43
상태
완료
공개여부
공개
Date
생성자
작업자

익명 클래스란

익명 객체(익명 클래스)는 말 그래도 이름이 없는 객체 혹은 이름이 없는 클래스로 무명 클래스라고도 불린다.
이름이 없다는 것은 다시 불릴 필요가 없기 때문에 기억되지 않는다는 의미로, 프로그램에서 일시적으로 한 번만 사용되고 버려지는 객체를 말한다. 재사용 되지 않기 때문에 확장성이 좋지 못하다.
UI 이벤트처리나 스레드 객체 등 단발성 이벤트를 처리하는 경우나, 비즈니스 로직이 제각각이라 재사용성이 없고 확장성을 활용하는 것이 유지보수에서 더 불리할 경우에 사용된다.
클래스를 별도로 만들 필요없이 코드에서 익명 객체를 생성 및 정의하여 사용되고 소멸하기 때문에, 덜 귀찮고 유지보수에 유리하다.

익명 클래스 구현 방법

public class Insect { void attack() { System.out.println("공격하기"); } }
Java
복사
1.
필드의 초기값으로 구현하기
public class Anonymous { Insect spider1 = new Insect() { String name = "거미1"; void cobweb() { System.out.println(name + "거미줄 치기"); } @Override void attack() { System.out.println(name + "공격하기"); } } }
Java
복사
2.
로컬변수의 초기값으로 구현하기
public class Anonymous { void method1() { Insect spider2 = new Insect() { String name = "거미2"; void cobweb() { System.out.println(name + "거미줄 치기"); } @Override void attack() { System.out.println(name + "공격하기"); } } spider2.attack(); } }
Java
복사
3.
매개변수로 구현하기
public class Anonymous { void method2(Insect spider3) { spider3.attack(); } }
Java
복사
익명 클래스 사용하기
public class AnonymousExample { 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("그냥 마구잡이로 친다."); } @Override void attack() { System.out.println(name + " 공격 안하고 후퇴한다.."); }; }); //익명객체 내부에서 새롭게 정의된 필드,메서드는 부모객체로 생성된 spider1에서 접근할 수 없음!!! a.spider1.name = "왕거미"; //익명객체에서 새롭게 정의된 필드 (접근불가) a.spider1.cobweb(); //익명객체에서 새롭게 정의된 메서드 (접근불가) } }
Java
복사

익명 구현 객체

위의 예시들은 Insect라는 클래스를 두고 그를 상속하여 익명 클래스를 생성하는 상속 익명 객체이다.
익명 클래스의 진가는 인터페이스를 익명 객체로 선언하여 사용하는 경우이다. 익명 클래스는 일회성 오버라이딩의 용도로 사용되는데, 추상화 구조인 인터페이스를 일회용으로 구현하여 사용하는 경우 시너지가 매우 잘 맞는다.
interface IAnimal { public String bark(); // 추상 메소드 public String run(); } public class Main { public static void main(String[] args) { // 인터페이스 익명 구현 객체 생성 IAnimal dog = new IAnimal() { @Override public String bark() { return "개가 짖습니다"; } @Override public String run() { return "개가 달립니다"; } }; // 인터페이스 구현 객체 사용 dog.bark(); dog.run(); } }
Java
복사
위를 보면 인터페이스를 클래스 생성자처럼 초기화하여 인스턴스화 한 것처럼 보이지만, 사실 자식 클래스를 생성해 implements하고 클래스를 초기화 한 것과 다름없다.
추상 클래스(abstract class)도 이런 방식으로 익명 구현 객체 생성이 가능하다.
상속 익명 객체와의 차이점은 익명 구현 객체는 인터페이스에서 메소드 정의를 통해 사용해야하는 규약으로 규격화에 도움이 된다는 점이다.
익명 클래스 기법은 자바 문법을 간결하게 만드는데 초점을 두고, 이는 java 8의 람다식 문법과 매우 잘 어울린다.
Operate operate = new Operate() { public int operate(int a, int b) { return a + b; } }; // 람다식으로 줄이기 Operate operate = (a, b) -> { return a + b; }; // 더 짧게 줄이기 (리턴 코드만 있다면 생략이 가능) Operate operate = (a, b) -> a + b;
Java
복사
다만 람다식을 통해 익명 클래스를 사용하려면, default 메서드 제외하고 단 하나의 추상 메서드만 선언되어 있는 인터페이스만 가능하다.
인터페이스의 가장 큰 본질은 다중 상속(구현)이 가능하다는 것인데, 익명 구현 객체는 오직 하나의 인터페이스만 구현하여 객체를 생성한다는 한계가 있다.