알고리즘

익명객체 ( Anonymous Object )

고유빙글 2021. 12. 3. 10:20

 : 익명 객체 ( Anonymous Object )
     익명 클래스
     클래스 이름이 없는 객체
     어떤 클래스를 상속하거나 인터페이스를 구현하여야 함 
     클래스를 정의하지 않고, 객체를 정의하는 방법으로 1회용 클래스를 사용한다.
     재사용이 불가능한 클래스 ( 객체를 1번 만드는 용도 )
     이벤트 객체, 스레드 객체, 람다식, 스트림 등에서 사용한다.

     등의 설명을 찾아볼 수 있었고, 솔직히 무엇인지 왜 사용하는지 처음에 잘 이해가 안갔다.

     나는 다음과같이 이해했는데,
     객체를 만드는데 이름이 없는 클래스를 통해 만들것이다. 그리고 이 클래스는 선언하는 클래스를 상속해서
     만들것이다.

     이름이 없기에 다시 호출하거나 선언할 수 없다. 그래서 1회용이다.

     이 말을 코드와 같이 보자.

    

public class Man {
	String name;
	int age;
	
	public void print() {
		System.out.println("name : "+name+", age : "+age);
	}
	
	public Man() {	}
	
	public Man(String name, int age) { 
		this.name = name;
		this.age = age;
	}
}

 

     우선 기본이 될 Man 클래스이다.

     이를 선언할때

Man m = new Man("아빠", 30);

     이런 식으로 선언하는 것이 일반적이다.

     그런데

		Man c = new Man() {
			
			String name = "자식";
			int age = 10;
			
			@Override
			public void print() {
				System.out.println("name : "+name+", age : "+age+". This Man is anonymous.");
			}
		};

     이렇게 선언하는 것이다.

		Man c = new Man() /* 여기에 마치 클래스이름이 있다고 생각하자 */ {     // <-- 그리고 여기에
									// 그 클래스에 대한 내용이 담긴다.
			String name = "자식";
			int age = 10;
			
			@Override
			public void print() {
				System.out.println("name : "+name+", age : "+age+". This Man is anonymous.");
			}
		};

 

     그럼 c라는 변수에는 Man 클래스를 상속받은, 이름을 지정하지 않은 클래스가 담기게 되는 것이고, 

     이 이름을 지정하지 않은 클래스의 필드는 이름이 없기때문에 다시 접근할 수 없어 1회용이 되는 것이다.

 

     신기한건 지금의 경우에는 

   

 

     이런식으로 name="자식", age=10 값이 잘 호출되는데

     오버라이드한 함수를 주석처리하면 

		Man c = new Man() {
			
			String name = "자식";
			int age = 10;
			
			public void message() {
				System.out.println("Test Message.");
			}
			
//			@Override
//			public void print() {
//				System.out.println("name : "+name+", age : "+age+". This Man is anonymous.");
//			}
		};

 

     이렇게 null과 0으로 나온다.

     이 부분은 좀 더 공부를 해봐야겠다.

 

     이렇게가 기본적인 익명객체의 설명이고 추가적인 활용을 하나 더 소개하겠다.

public class Testfiled {

	public static void main(String[] args) {
    
		Man m2 = manDetail(
					new Man() {
						String name = "anonymous";
						int age = 100;
						@Override
						public void print() {
							System.out.println("name : "+name+", age : "+age+". This Man is anonymousObject.");
						}
					}
				);
		
		m2.print();
        
	}
	
	public static Man manDetail(Man man) {
		return man;
	}

}

 

     이 경우 3번째 문장의 코드부분이고,

     메소드의 인자로 익명객체를 사용하는 방법이다.

 

 

 

     연습한 전체 코드는 이렇다.

public class Testfiled {

	public static void main(String[] args) {
		
		Man c = new Man() {
			
			String name = "자식";
			int age = 10;
			
			public void message() {
				System.out.println("Test Message.");
			}
			
//			@Override
//			public void print() {
//				System.out.println("name : "+name+", age : "+age+". This Man is anonymous.");
//			}
		};
		
		Man m = new Man("아빠", 30);
		
		m.print();
		c.print();
//		c.message();	// 선언은 되지만 사용할 수 없다.
		
		
		Man m2 = manDetail(
					new Man() {
						String name = "anonymous";
						int age = 100;
						@Override
						public void print() {
							System.out.println("name : "+name+", age : "+age+". This Man is anonymousObject.");
						}
					}
				);
		
		m2.print();
	}
	
	public static Man manDetail(Man man) {
		return man;
	}

}

 

     이 후 추가글에 c.message()부분과 오버라이드 메소드에 주석처리한것에대한 자세한 이유를 고민해보고

     작성하겠다.

 

     해당 익명객체를 기재하게 된 것은 Comparable, Comparator를 공부하다 공부하게 된 것이고,

     Comparable, Comparator를 공부하게 된 것은 

     Heap을 공부하다 온 것이기 때문에 우선 진도를 좀 나가야 머리속에서 좀 더 깊은내용에대해

     들여다 볼 여유가 생길 것 같다.