모든 클래스의 최상위 클래스(root)인 Object 클래스의 메서드에서 equals 를 재정의(오버라이딩)하는 것을 시도해보면 자연스럽게 다형성에 대해서 이해할 수 있다.
class A {
String name;
public A(String name) {
this.name = name;
}
}
class ObjectDem {
public static void main(String[] args) {
A a1 = new A("Kyu");
A a2 = new A("Kyu");
System.out.println(a1 == a2);
System.out.println(a1.equals(a2));
}
}
등가비교연산자 ==
와!=
는 두 피연산자에 저장되어 있는 값이 같은지, 또는 다른지를 비교하는 연산자이다. 참조형의 경우 객체의 주소값을 저장하기 때문에 두 개의 피연산자(참조변수)가 같은 객체를 가리키고 있는지를 알 수 있다.
참조형 변수에 사용할 수 있는 연산자는 ==
와 !=
그리고 캐스트 연산자 뿐이다. String에는 예외적으로 문자열결합에 +
을 사용하는 것을 허용한다.
위에 있는 코드를 실행해보면 아래와 같이 출력된다.
false
false
a1
과 a2
는 당연히 새로운 객체를 생성했으니 주소값이 다르기 때문에 false
라고 나온다. equlas()
로 비교하면, Object클래스의 equals()
의 내부 코드를 보면 객체 자체를 비교 연산자==
로 비교한다. 따라서 ==
로 비교하는 것과 같은 결과값이 나온다.
만약에 넣어준 파라미터의 값이 같다면 true를 보내주고 싶을 때 A
클래스 내에 다음과 같이 코드를 추가하면 된다.
@Override
public boolean equals(Object obj) {
return this.name == ((A)obj).name;
}
equals를 먼저 Object 타입으로 매개변수를 받는다. 들어온 매개변수는 Object 타입이기 때문에 A
클래스 내의 필드를 사용할 수 없다. 그래서 A
로 형변환 (downcasting) 을 해줘야한다. 코드와 같이 ((A)obj)
와 같이 downcasting하면 A
의 필드를 사용할수있다.
그런 뒤에 가독성을 위해 this
를 붙여서 this
의 name
과 ((A)obj))
의 name
을 비교해서 return 하면 된다.