달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
어렵게 꼬아놔서 뭔 소리인지 잘 몰랐는데 그냥 요약된 부분만 보니깐 알겠더라..

한마디로 수학 으로 생각하면 된다.

재귀적 : a=a
대칭적 : a=b  b=a
이행적 : a=b  b=c  a=c
일관적 : a=b 같은 상태에서 a와 b의 값이 변함이 없다면 항상 a=b

개인적으로 자주 겪었던 대칭적 부분만 일단 자세히 짚어보았다.

equals 오버라이딩 공부할때 작성했던 소스를 책 예제로 약간 개조해보자면

@Override
    public boolean equals(Object obj) {
        if((obj instanceof Quiz)&& obj != null ) {
            return answer.equalsIgnoreCase(((Quiz)obj).answer);
        }
        if((obj instanceof String) && obj != null){
            return answer.equalsIgnoreCase((String)obj);
        }
        return false;
    }

이렇게 한다음 q1,q2를 이런식으로 선언했다.

Quiz q1 = new Quiz("asd");
String q2 = "Asd"

그 다음 q1.equals(q2) 결과와 q2.equals(q1)의 결과를 비교했다.

첫번째는 같다. 두번째는 다르다 가 나왔다.

a=b b=a 라는 대칭적 계약의 위반이다. Quiz의 equals 메소드는 일반 문자열을 처리하고 있는 반면 String equals 메소드는

대소문자를 구분하지 않는 문자열을 인식하지 못하는 것이다.

이것을 고쳐보자면


@Override
    public boolean equals(Object obj) {
        return obj instanceof Quiz && ((Quiz)obj).answer.equalsIgnoreCase(answer);
    }

두 조건다 false 를 반환하게 된다.

이 예제의 의미를 잘 몰라서 자초스 뉴와이 님의 도움으로 알게 되었다.

뉴와이 님의 답변 전문

책 내용대로 라도 false false를 반환하게 설계하라고 추천하고 있는겁니다.

책에서 equlas()의 대칭성을 설명하는 부분이었고,
이전의 CaseInsensitiveString클레스에서
String클레스 형의 객체와 비교 가능하게 설계되어있을 겁니다.
하지만 String클레스에서 CaseInsensitiveString형의 비교 불가능하게 되어있죠..

ex)
CaseInsensitiveString a = new CaseInsensitiveString("Polish");
String b = "polish";

a.equals(b); //true
b.equals(a); //false
여서 대칭성의 문제로
CaseInsensitiveString에서
String형의 객체와의 비교처리를 지원하지 말라고 추천하는 내용입니다.

a에서의 equlas()만 지원하는 일방적인 equals 형태이죠.
이걸 방지하자는 내용이죠...

:
Posted by 유쾌한순례자