본문 바로가기

Java

13 - 2 장 익명 이너 클래스

1. 익명 이너 클래스의 정의와 특징 

 

 - '이름을 알 수 없는 이너 클래스'

 - 인스턴스 익명 이너 클래스 / 지역 익명 이너 클래스 

interface C {
	public abstract void bcd();
}

1) 인터페이스를 상속한 이너 클래스를 생성해 인터페이스 객체 생성

class A1 {
	C b = new B();
    void abc() {
    	//메서드 내용
    }
    class B implements C {
    	public void bcd() {
        	//메서드 구현
         }
    }
}

 - 인터페이스 C를 구현하고 있는 인스턴스 이너 클래스 B

 - C b = new B(); 

  - 인터 페이스 C 타입의 참조 변수, 생성자 B()로 객체를 생성해 초기화 

- abc() 메서드 정의 

- C타입의 객체를 생성하기 위해 이너 클래스를 B라는 이름으로 직접 정의해 사용 

 

package InnerInterface;

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 InnerInterface {
	public static void main(String[] args) {
		//객체 생성 및 메서드 호출
		A a = new A();
		a.abc();
	}
}

2) 익명 이너 클래스를 활용해 인터페이스 객체 생성

class A2 {
	C b = new C() {
    	public void bcd() {
        	//메서드 구현
         }
    };
    
    void abc() {
    	//메서드 내용
    }
}

 - C 타입의 생성자를 호출한 후 중괄호 안에 인터페이스에 포함된 추상 메서드 bcd()를 구현해 표현

 - 컴파일러는 인터페이스 C를 상속받아 추상 메서드를 구현한 클래스를 내부적으로 생성한 후 해당 클래스로 객체를 생성해 참조변수에 대입 

package InnerInterface;

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

interface C {
	public abstract void bcd();
}
public class InnerInterface {
	public static void main(String[] args) {
		//객체 생성 및 메서드 호출
		A a = new A();
		a.abc();
	}
}

 

 - 인터페이스 C를 구현한 자식 클래스에서 메서드(cde())를 추가로 정의했을 때 

class B implements c {
	public void bcd() {
    	//오버라이딩된 메서드
    }
    public void cde() {
    	//추가 메서드
    }
}

B b = new B();
b.bcd(); //O
b.cde(); //O

  - 자식 클래스 타입으로 객체를 선언하고 생성하면 오버라이딩된 메서드와 추가 메서드를 모두 사용

  - bcd() 메서드와 cde()메서드 모두 클래스 B 내부에서 정의돼 있으며, 참조 변수가 B 타입이므로 두 메서드 모두 호출 가능

C c = new C() {
	public void bcd() {
    	//오버라이딩된 메서드
        cde(); //내부적으로 호출가능
    }
    public void cde() {
    	//추가 메서드 
    }
};

c.bcd(); //o
c.cde(); //x -> C 타입에 없음

 - 익명 이너 클래스를 사용할 때는 항상 부모 타입으로만 선언할 수 있으므로 추가로 정의한 메서드 cde()는 항상 호출할 수 없음

 

2. 익명 이너 클래스를 활용한 인터페이스 타입의 입력매개변수 전달

 

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

 - 인터페이스 A에는 추상 메서드 abc() 포함

 - 클래스 C에는 인터페이스 A 타입의 객체를 입력매개변수로 포함하고 있는 메서드 cde(A a) 포함

 - 클래스 C의 객체를 생성한 후 cde(A a) 메서드를 호출하기 위해서는 입력매개변수로 사용될 인터페이스 A 타입의 객체를 생성해야 함

 - 인터페이스로는 객체를 직접 생성할 수 없으므로 인터페이스 A를 구현한 자식 클래스의 객체가 전달돼야 함 

 

 1) 클래스 정의 및 참조변수명을 사용/ 미사용 했을 때 입력매개변수 객체 전달

 

  -  인터페이스 A의 자식클래스 B를 직접 정의할 때 

class B implements A [
	public void abc() {
    	//...
     }
}

  - 자식 클래스의 생성자를 호출함으로써 객체는 얼마든지 생성 가능 

 

C c = new C();

//방법 1
A a1 = new B();
c.cde(a1);

//방법 2
c.cde(new B());

 방법 1

  - B() 생성자를 이용해 생성한 객체를 A타입의 참조 변수에 저장하고, 입력매개변수로 참조 변수를 넘겨 줌

  - 참조 변수 a1의 역할은 객체의 참좃값을 전달하기 위해서 사용

 

 방법 2 

  - 참조 변수를 사용하지 않고 메서드 입력매개변수 위치에서 바로 new B()와 같이 객체를 생성하면 생성된 객체의 참좃값이 메서드로 전달

 

package InnerInterface;

interface A {
	public abstract void abc();
}

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

public class InnerInterface {
	public static void main(String[] args) {
		C c = new C();
		//방법 1. 클래스명 O + 참조 변수명 O
		A a = new B();
		c.cde(a);
		//방법 2. 클래스명 O + 참조 변수명 X
		c.cde(new B());
	}
}

 

 2) 클래스 미정의 및 참조 변수명을 사용/미사용했을 때 입력매개변수 객체 전달

 

  - 자식 클래스를 별도로 정의하지 않고, 익명 이너 클래스를 사용

C c = new C();

//방법 3
A a = new A() {
	public void abc() {
    	//...
    }
};
c.cde(a);

//방법 4
c.cde(new A() {
	public void abc() {
    	//...
     }
 });

 방법 3

  - 익명 이너 클래스를 사용해 객체를 생성하고, 객체를 참조하는 참조 변수(a)를 cde()메서드의 입력매개변수로 전달

 

 방법 4

  - 참조 변수를 대입하지 않고, 메서드 입력매개변수 자리에서 곧바로 익명 이너 클래스 객체를 생성해  전달하는 방식

 

package InnerInterface;

interface A {
	public abstract void abc();
}

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

public class InnerInterface {
	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("입력매개변수 전달");
			}
		});
	}
}

'Java' 카테고리의 다른 글

14 - 1장 예외  (0) 2023.06.12
13 - 3 장 이너 인터페이스  (0) 2023.06.05
13 -1 장 이너 클래스  (0) 2023.06.04
12 - 2장 인터페이스  (0) 2023.06.04
12-1장 추상 클래스  (0) 2023.06.02