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 |