본문 바로가기

Programming/OOP

java.lang.Object 는 왜 최상위 클래스일까요? - OOP

며칠전 면접때 면접관께서 물어보셨습니다.
"왜 java.lnag.Object 는 interface로 구현하지 않고 클래스로 구현하였나요?"

순간 말문이 막혔습니다. "왜 클래스로 구현하였을까?"
너무나 뻔한 답이 머릿속의 여러 생각들이 입밖으로 나오질 않더군요.

모든 객체들이 필요할 수 있는 메소드들을 생각해보면 되는데 말이죠.
그것은 Object 클래스의 메소드들을 살펴보면 알 수 있겠죠. 
 
객체를 shallow copy 해주는 Object : clone()
객체와 등가되는 객체인지  boolean : equals(Object obj)
객체가 참조되는 무엇이 없으면 가비지컬렉터에 수집되는 void : finalize()
객체의 클래스 타입을 돌려주는 Class<?> : getClass()
객체의 해쉬코드 값을 리턴하는 int : hashCode()
객체에 대해 사용자가 알 수 있게끔 객체값을 String으로 리턴하는 String : toString()

외에는 쓰레드 safe한 객체들을 위한 notify, notifyAll, wait 등의 메소드들이 있습니다.

생각해보면 모든 객체들이 위의 메소드들을 필요로 하는 것은 아닙니다.
하지만 Obejct 클래스의 메소드들은 어떠한 객체이든 지원되어야 하는 메소드들이죠.
저러한 메소드들을 구현한다고 생각해보면...벌써부터 어두운 노가다의 먹구름이 보이죠? ㅎㅎ

java를 개발한 개발자들의 OOP 적 사고를 다시한번 엿보는 시간이었네요.


-------------2012. 7. 18 추가
요새 개발을 하면서 DTO(VO)와 같은 클래스들을 매우 자주 작성합니다.
이때 가장 손쉽게 Object 클래스로부터 override하여 작성하는 메소드는
toString 클래스입니다.
만약 Object의 toString 클래스를 그대로 작성하다가는 객체의 패키지구조와 클래스이름, 해쉬코드가
출력될 것입니다.
이를 방지하기 위해서는 반드시 toString을 override해주어야하죠.
또한 만약에 DTO가 같은 지에 대해서 일반적인 경우와 달리 해주어야 하는 경우가 있습니다.
즉, Object의 equals() 메소드가 달라져야 하는 경우가 있죠.
문제는 Object의 equals() 메소드는 내부적으로 hashCode() 메소드를 호출하여 비교합니다.
결국 equlas() 메소드의 변경은 hashCode() 메소드의 변경까지 요구하게됩니다.
헌데 이때 아무런 생각없이 hashCode() 메소드를 작성하다간 훗날 해당 객체들을
HashMap같은 hashCode를 기준으로 객체를 담는 자료구조에 담다간 난리납니다.
(그 이유는 bucket이란 개념이 있는데 이거... 나중에 정리 좀 해야겠네요;;;)

여튼 java.lang.Object가 최상위 클래스이면서 구현된 세부적인 메소드들이 존재하는 이유는
그만큼 이 메소드들에 대해서 정확히 알고 접근해야하는 말이기도 하네요.