426p
익명 객체를 만들기 위한 조건이 있습니다. 어떤 클래스를 상속하거나 인터페이스를 구현해야 합니다.
1.익명 자식 객체
자식 클래스를 명시적으로 선언하는 이유는 어디서건 이미 선언된 자식 클래스로 간단히 객체를 생성해서 사용할 수 있기 때문입니다. 우리는 이것을 재사용성이 높다고 말합니다. 그러나 자식 클래스가 재사용되지 않고 오로지 특정 위치에서 사용할 경우라면 자식 클래스를 명시적으로 선언하는 것은 귀찮은 작업이 됩니다. 이 경우에는 익명 자식 객체를 생성해서 사용하는 것이 좋습니다. 익명 자식 객체를 생성하는 방법은 다음과 같습니다.
부모클래스 [필드|변수] = new 부모클래스(매개값,...) { \\필드 }; |
* 하나의 실행문이므로 ';'을 반드시 붙여야 합니다.
'부모클래스(매개값,...) { ...}'은 부모 클래스를 상속해서 중괄호 {}와 같이 자식 클래스를 선언하라는 뜻입니다. 그리고 new 연산자는 이렇게 선언된 자식 클래스를 객체로 생성합니다.
'부모클래스(매개값,...)'은 부모 생성자를 호출하는 코드로 매개값은 부모 생성자의 매개 변수에 맞게 입력하면 됩니다. 중괄호 내부에는 필드나 메소드를 선언하거나 부모 클래스의 메소드를 재정의하는 내용을 작성합니다. 일반적으로 재정의 메소드가 많이 나옵니다. 일반 클래스와 달리 익명 자식 객체는 생성자를 선언할 수 없습니다.
익명 자식 객체는 클래스의 필드, 메소드 및 부모 타입을 매개변수로 가지는 메소드의 매개변수로서 선언될 수 있다. 익명 자식 객체에 새롭게 정의된 필드와 메소드는 익명 자식 객체 내부에서만 사용되고, 외부에서는 접근할 수 없다. 그 이유는 익명 자식 객체가 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용할 수 있기 때문이다.
예를 들어 다음 코드에서 A 클래스의 필드인 field로는 childField, childMethod()에 접근할 수 없습니다.
class A {
Parent field = new Parent() {
int childField;
void childMethod() {}
@Override
void parentMethod() {
childField = 3;
childMethod();
}
};
void method() {
field.childField = 3; (x)
field.childMethod(); (x)
field.parentMethod(); (o)
2. 익명 구현 객체
구현 클래스가 재사용되지 않고 오로지 특정 위치에서 사용할 경우라면 구현 클래스를 명시적으로 선언할 필요는 없습니다. 이 경우에는 익명 구현 객체를 생성해서 사용하는 것이 좋은 방법입니다.
인터페이스 [필드|변수] = new 인터페이스() { //인터페이스에 선언된 추상 메소드의 실체 구현 //필드 //메소드 }; |
인터페이스() {...}는 인터페이스를 구현해서 중괄호 {}와 같이 클래스를 선언하라는 뜻입니다. 중괄호 안에는 인터페이스에 선언된 모든 추상 메소드의 실체 메소드를 재정의해야 합니다. 그렇지 않으면 컴파일 에러가 발생합니다. 또한 추가로 필드와 메소드를 선언할 수 있지만, 실체 메소드에서만 사용이 가능하고 외부에서는 사용할 수 없습니다.
+ 매개변수나 로컬변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 익명 객체에서 지속적으로 사용할 수 없습니다. 자바는 이러한 문제를 해결하기 위해서 컴파일 시 익명 객체에서 사용하는 매개변수나 로컬변수 값을 익명 객체 내부에 복사해두고 사용합니다. 그리고 매개변수나 로컬변수가 수정되어 값이 변경되면 익명 객체에 복사해 둔 값과 달라지므로 매개 변수나 로컬 변수를 final로 선언할 것을 요구합니다.
다음 예제는 한 메소드 안에 익명 객체가 쓰일 때, 그 메소드 안에 있는 매개 변수와 필드 들은 모두 final 처리 된다는 것을 보여준다.
'java' 카테고리의 다른 글
java.lang 패키지 (0) | 2021.01.28 |
---|---|
java 예외 처리 - 예외 클래스 (0) | 2021.01.27 |
java 중첩 클래스, 중첩 인터페이스 (0) | 2021.01.26 |
java 인터페이스(interface) (0) | 2021.01.25 |
추상 클래스, 추상 메소드 (0) | 2021.01.25 |