본문 바로가기

Programming/JAVA

중첩 클래스&인터페이스(5) - 익명 객체 2

java logo image

 

 

바로 앞의 아티클에서, 익명 객체의 기본적인 생성 방식과 개념에 대해서 함께 살펴보았습니다. 코드 예제를 통해서 익명 객체를 생성하는 몇 가지 패턴에 대해서 살펴보도록 하겠습니다. 

 

 

중첩 클래스&인터페이스(5) - 익명 객체 1

익명(anonymous) 객체는, 말 그대로 이름을 갖지 않는 객체를 의미합니다. 그런데 JAVA에서의 익명 객체에서 갖는 큰 특징은, 단독으로 익명 객체를 생성할 수가 없다는 점입니다. 단독으로 생성할

nozeroslope.tistory.com

 

 


 

 

우선 임의의 부모 클래스 Parent가 있다고 가정해 보겠습니다. A라는 클래스에서 Parent를 상속받는 자식 클래스를 익명 개체로 구현한다면, 다음과 같이 구현하게 됩니다. 참고로 부모 클래스 Parent에 선언된 메서드 parentMethod( ) 역시 재정의하여 사용하는 자식 클래스입니다. 

 

public class A {
	Parent field = new Parent() {
		int childField;
		void childMethod() {}
		@Override
		void parentMethod() {}
	};
}

 

 

혹은, 해당 익명 객체를 메서드 내의 로컬 변수로 선언하는 것도 다음과 같이 가능합니다. 

 

public class A {
	void method() {
		Parent localVar = new Parent() {
			int childField;
			void childMethod() {}
			@Override
			void parentMethod() {}
		};
	}
}

 

 

만일 어떤 메서드의 파라미터가 Parent 타입으로 선언되어 있다고 가정해 보겠습니다. 그럼 원칙적으로 Parent의 자식 인스턴스도 파라미터 인자 값으로 전달이 가능합니다. 자동 변환이 이루어질 테니까요.

 

그런데 new Parent 키워드로 만든 익명 객체도 Parent의 자식 인스턴스를 만드는 과정이라고 했습니다. 결국, 이 익명 객체도 Parent의 자식 인스턴스로서 해당 파라미터에 인자로 전달이 가능하다는 뜻이 됩니다. 아래 예제를 보겠습니다. 

 

public class A {
	void method1(Parent parent) {}
	void method2() {
		method1(new Parent() {
			int childField;
			void childMethod() {}
			@Override
			void parentMethod() {}
		});
	}
}

 

 


 

 

한 가지 더, 익명 객체로 자식 클래스를 생성하게 되는 경우 헷갈릴 수 있는 부분인데 - 익명 객체는 Parent를 상속받는 자식 (익명)객체라고 했습니다. 그런데, 익명 객체 선언 시 위에서 클래스 타입을 무엇으로 선언했죠? 바로 Parent, 즉 부모 클래스 타입으로 선언했습니다. 

 

이럴 경우, 익명 객체(자식 클래스 인스턴스)에서 선언된 익명의 자식 인스턴스에 선언된 자식의 필드/메서드는 사용이 가능할까요? 기본적인 원칙에 따라서 사용이 불가능합니다. 이는 클래스 상속의 기본 다형성 원리에서 배운 내용이며, 이 속성은 그대로 적용됩니다. 아래 예제를 보겠습니다. 

 

public class A {
	Parent field = new Parent() {
		int childField;
		void childMethod() {}
		@Override
		void parentMethod() {}
	};
	
	void method() {
		// field.childField = 100;
		// field.childMethod();
		field.parentMethod();
	}
}

 

 

위에서 익명의 자식 객체가 Parent 타입으로 형 변환이 일어난 것과 마찬가지의 현상이 벌어진 것입니다. 그래서 Parent 타입으로 형 변환이 되었다고 가정하면, (익명의) 자식 객체 고유의 필드로 선언된 것들은 사용이 불가능하고, Parent 클래스에 선언된 메서드(오버라이드 한 경우도)만이 사용 가능한 것입니다.