3장 - 모든 객체의 공통 메서드

자바의 모든 class는 Object class를 상속한다.

Object class는 객체를 만들 수 있는 구체 클래스지만 기본적으로 상속해서 사용하도록 설계되었다.

⇒ 모든 클래스는 Object의 final이 아닌 메서드 (equals, hashCode, toString, clone, finalize 등을 규약에 맞게 오버라이딩해야 한다. 그렇지 않으면 대상 클래스가 규약을 준수한다고 가정하는 클래스 (HashSet, HashMap 등)이 오작동할 수 있다.

목표: final이 아닌 Object 메서드들을 언제 어떻게 재정의해야 하는지를 알아보자.


들어가기 전에…

[ 클래스의 종류 ]
1. 구체 클래스 (Concrete class): 클래스 내의 메서드를 모두 구현한 클래스이며 new 키워드로 객체 생성이 가능하다.
2. 추상 클래스 (Abstract class): 구체 클래스가 아닌 클래스이며 하나 이상의 미구현 메서드를 가지고 있고 new키워드로 객체 생성이 불가능하다.

[ 상속 관계에 있는 클래스 ]
상속 관계에 있는 클래스는 부모 클래스와 자식 클래스로 구분할 수 있다.
기본형 타입을 서로 형변환 할 수 있듯이, 자바의 상속 관계에 있는 부모 클래스와 자식 클래스 간에는 형변환이 가능하다.

1. Upcasting: 자식을 부모로 형변환하는 것 
2. Downcasting: 부모를 자식으로 형변환하는 것 (부모는 자식의 멤버를 모두 가지고 있지 않다)

아래의 상황에 하나라도 해당하면 equals를 재정의하지 않는 것이 좋다

  1. 각 인스턴스가 본질적으로 고유하다.
  2. 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없다.
  3. 상위 클래스에서 재정의한 equals 가 하위 클래스에도 딱 들어맞는다.
  4. 클래스가 private이거나 package-private이고 equals 메서드를 호출할 일이 없다.

그렇다면 언제 equals를 재정의해야 하는가?

⇒ 두 객체가 물리적으로 같은지가 아니라 논리적으로 같은지를 확인할 때 (주로, 값 클래스)

equals가 논리적 동치성을 확인하도록 재정의해두면, 그 인스턴스는 값을 비교하길 원하는 프로그래머의 기대에 부응함은 물론 Map 의 키와 Set 의 원소로 사용할 수 있게 된다.