언어/Java

[자바 완전 정복] Chap13 - 익명이너클래스와 이너인터페이스

Damgome 2023. 5. 25. 18:09

익명이너클래스

익명 이너클래스 < 익명(이름을 알 수 없음) + (인스턴스)이너클래스

 

  • 이너클래스 직접 만들기
interface C{
	public abstract void bcd();
}

class A{
	C b = new B(); //필드
	
	void abc() { //메서드
		b.bcd();
	}
	
	class B implements C{ //이너클래스
		
		public void bcd() {
			System.out.println("lululu");
		}
	}
}
  • 익명이너클래스 만들기
interface C{
	public abstract void bcd();
}

class A{
	C b = new C() {  //C를 상속받아 bcd()메서드를 오버라이딩한 익명 이너클래스의 객체
		public void bcd() {
			System.out.println("lululu");
		}
	};
	
	void abc() {
		b.bcd();
	}
}

 

익명 이너클래스를 사용하는 경우, 이름이 없어, 한 번에 객체를 2개 이상 생성 불가하다!

interface C{
	public abstract void bcd();
}

public class Practice_01 {
	public static void main(String[] args) {
		C c = new C() {
			public void bcd() {
				System.out.println("C인터페이스의 bcd");
				cde();
			}
			void cde() {
				System.out.println("C인터페이스의 cde");
			}
		};
		
		c.bcd();
		//c.cde(); //C 타입에 없기 때문에 오류난다..즉, 익명이너클래스를 사용하면
		//추가로 정의한 메서드는 쓸 수가 없음
	}
}

 

익명이너클래스를 활용하여 인터페이스 타입의 매개변수 전달하는 법

  • 방법 1, 방법2 : 클래스명이 있을 때
interface A{
	public abstract void abc();
}

class B implements A{
	public void abc() {
		System.out.println("meow");
	}
}

class C{
	void cde(A a) {
		a.abc();
	}
}
public class Practice_01 {
	public static void main(String[] args) {
		C c = new C(); 
		//방법1. 클래스명 O, 참조변수명 O
		A a1 = new B();
		c.cde(a1);
		
		//방법2. 클래스명 O, 참조변수명 X
		c.cde(new B());
	}
}
  • 방법 3, 4 : 클래스명이 없을 때 (방법 4가 가장 많이 사용된다)
interface A{
	public abstract void abc();
}

class C{
	void cde(A a) {
		a.abc();
	}
}
public class Practice_01 {
	public static void main(String[] args) {
		C c = new C(); 
		//방법3. 클래스명 X, 참조변수명 O
		A a = new A() {
			public void abc() {
				System.out.println("meow");
			}
		};
		c.cde(a);
		
		//방법4. 클래스명 X, 참조변수명 X
		c.cde(new A(){
			public void abc() {
				System.out.println("meow");
			}
		});
	}
}

이너인터페이스

이너 인터페이스 == 내부 인터페이스

특징 1. 외부 클래스와 밀접한 관계가 있는 경우에 정의한다

특징 2. UI의 이벤트 처리에 가장 많이 사용한다(클릭, 터치 등)

특징 3. static을 생략한 경우 컴파일러가 자동으로 static을 삽입해 준다(static 이너 인터페이스만 가능)

 

생성 클래스명 : A.class(외부 클래스), A$B.class(이너 인터페이스)

 

객체생성 및 사용

이너 인터페이스를 가진 외부 클래스 A가 있다고 가정!

class A{
	static interface B{
		void bcd();
	}
}

#방법 1. 인터페이스 구현 클래스 생성 및 객체 생성

class C implements A.B{
	public void bcd() {
		System.out.println("meow");
	}
}
public class Practice_01 {
	public static void main(String[] args) {
		C c = new C();
		c.bcd();
	}
}

#방법 2. 익명이너클래스 사용

public class Practice_01 {
	public static void main(String[] args) {
		A.B a = new A.B() {
			public void bcd() {
				System.out.println("meow");
			}
		};
		
		a.bcd();
	}
}

example(1)

class A{
	interface B{
		public abstract void bcd();
	}
}

//방법 1-1. 이너인터페이스 구현 클래스 생성
class C implements A.B{
	public void bcd() {
		System.out.println("이너인터페이스 구현 클래스 생성");
	};
}
public class Practice_01 {
	public static void main(String[] args) {
		//객체 생성 방법 1-2. 구현 클래스로 객체 생성
		C c = new C();
		c.bcd();
		
		//2. 익명이너클래스로 객체 생성
		A.B b = new A.B() {
			public void bcd() {
				System.out.println("익명 이너클래스로 객체 생성");
			}
		};
		b.bcd();
	}
}

example(2)

class Button{
	OnClickListener ocl;
	void setOnClickListener(OnClickListener ocl) {
		this.ocl = ocl;
	}
	interface OnClickListener{
		public abstract void onClick();
	}
	void click() {
		ocl.onClick();
	}
}
public class Practice_01 {
	public static void main(String[] args) {
		
		//개발자 #1. 클릭했을 때 음악 재생
		Button button1 = new Button();
		button1.setOnClickListener(new Button.OnClickListener() {
			public void onClick() {
				System.out.println("개발자1. 음악 재생");
			}
		});
		
		button1.click(); 
		//개발자 #2. 클릭했을때 네이버 접속
		Button button2 = new Button();
		button2.setOnClickListener(new Button.OnClickListener() {
			public void onClick() {
				System.out.println("개발자2. 네이버 접속");
			}
		});
		
		button2.click();
	}
}

실습 예제

#1

package sec04_anonymousclass.EX01;

class A{
	C c = new B();
	
	void abc() {
		c.bcd();
	}
	class B implements C{
		public void bcd() {
			System.out.println("인스턴스 이너클래스");
		}
	}
	
}

interface C{
	public abstract void bcd();
}
public class AnonymousClass_1 {

	public static void main(String[] args) {
		//1. 객체 생성 및 메서드 호출
		A a = new A();
		a.abc(); //인스턴스 이너클래스
	}

}

#2

package sec04_anonymousclass.EX02;

class A{
	C c = new C() {
		public void bcd() {
			System.out.println("익명 이너클래스");
		}
	};
	
	void abc() {
		c.bcd();
	}
	
}

interface C{
	public abstract void bcd();
}
public class AnonymousClass_2 {

	public static void main(String[] args) {
		//1. 객체 생성 및 메서드 호출
		A a = new A();
		a.abc(); //익명 이너클래스
	}

}

#3

package sec04_anonymousclass.EX03;

interface A{
	public abstract void abc();
}
//#1. 자식클래스를 직접 생성
class B implements A{
	public void abc() {
		System.out.println("매개변수 전달");
	}
}
class C{
	void cde(A a) {
		a.abc();
	}
}
public class AnonymousClass_3 {

	public static void main(String[] args) {
		C c = new C();
		
		//#1. A타입의 객체 생성 : 방법#1. 클래스명 O, 참조변수명 O
		A a = new B();
		c.cde(a); //출력 : 매개변수 전달
	
		//#2. 클래스명 O, 참조변수명 X
		c.cde(new B()); //출력 : 매개변수 전달
	}

}

#4

package sec04_anonymousclass.EX04;

interface A{
	public abstract void abc();
}

class C{
	void cde(A a) {
		a.abc();
	}
}
public class AnonymousClass_4 {

	public static void main(String[] args) {
		C c = new C();
		
		//#방법3. 익명이너클래스로 객체생성(클래스명 X + 참조변수명 O)
		A a = new A() {
			public void abc() {
				System.out.println("매개변수 전달");
			}
		};
		c.cde(a);
		
		//#방법4. 클래스명 X + 참조변수명 X
		c.cde(new A() {
			public void abc() {
				System.out.println("매개변수 전달");
			}
		});
		
		
	}

}

#5

package sec05_innerinterface_EX01;

class A{
	static interface B{
		public abstract void bcd();
	}
}
class C implements A.B{
	public void bcd() {
		System.out.println("이너인터페이스 구현 클래스 생성");
	}
}
public class CreateObjectOfInnerInterface {
	public static void main(String[] args) {
		//객체생성방법 #1. 자식클래스 직접 생성
		A.B ab = new C();
		C c = new C();
		
		//객체생성방법 #2. 익명 이너클래스 생성
		A.B b = new A.B() {
			public void bcd() {
				System.out.println("익명이너클래스로 객체 생성");
			}
		};
	}
}

#6

package sec05_innerinterface_EX02;

class Button{
	OnClickListener ocl;
	void setOnClickListener(OnClickListener ocl) {
		this.ocl = ocl;
	}
	
	interface OnClickListener{
		public abstract void onClick();
	}
	
	void onClick() {
		ocl.onClick();
	}
}
public class ButtonAPIExample {
	public static void main(String[] args) {
		//1. 개발자1. 클릭했을 때 음악재생
		Button btn1 = new Button();
		btn1.setOnClickListener(new Button.OnClickListener() {
			public void onClick() {
				System.out.println("음악을 재생합니다");
			}
		});
		
		btn1.onClick();
		//2. 개발자2. 네이버접속
		Button btn2 = new Button();
		btn2.setOnClickListener(new Button.OnClickListener() {
			public void onClick() {
				System.out.println("네이버에 들어갑세다");
			}
		});
		
		btn2.onClick();
	}
}