JAVA

[JAVA]Object 클래스

당고개 2023. 11. 7. 22:48

1. 모든 클래스는 Object 클래스를 상속 받는다

class Fruit extends Object {
    private String name;

    Fruit(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }
}

Fruit 클래스가 있는데요. Fruit 클래스는 Object 클래스를 상속받고 있습니다. 이렇게 extends 키워드를 이용하여 명시적으로 선언하지 않는다 하더라도 Object 클래스를 상속받고 있습니다. (컴파일러가 처리합니다.)

 

우리는 이전에 다형성이라는 것을 배웠었는데요. Java 언어의 다형성의 특징을 통해 Fruit 인스턴스는 Object 참조 자료형 변수에 저장할 수 있습니다. 

 

case 다형성

Object fruit = new Fruit("사과");

case 매개 변수

class Test {

    public String getInstanceName(Object obj) {
        if (obj instanceof Fruit) {
            return "과일";
        } else if (obj instanceOf Car) {
            return "자동차";
        } else {
            return "그 외";
        }
    }
}
Test test = new Test();

Fruit fruit = new Fruit("사과");
String instanceName = test.getInstanceName(fruit);

System.out.println(instanceName); 
//과일

또한 메서드의 매개변수가 Object 참조 자료형인 경우 모든 클래스의 인스턴스를 전달 받을 수 있습니다.

 

2. Object 클래스를 상속 받기 때문에 Object 클래스의 메서드를 상속 받는다.

모든 클래스는 Object 클래스를 상속 받으며, Object 클래스의 요소를 사용할 수 있습니다.

 

Object 클래스의 메서드들

public class Object {

    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    ...
}

Object 클래스에는 다양한 메서드가 선언되어 있는데요. 현재는 각 메서드가 무슨 일을 하는지 알 수 없습니다. 그중 몇가지 중요한 것만 집고 넘어갑시다.

 

toString()

toString() 메서드는 메서드를 재정의하지 않는다면 기본적으로 인스턴스의 클래스 이름과 골뱅이, 인스턴스의 해시 코드를 16진수로 변환한 문자열을 반환합니다.

Fruit fruit = new Fruit("사과");

System.out.println(fruit.toString()); 

// Fruit@610455d6

toString() 메서드를 재정의하여 인스턴스의 의미 있는 정보를 제공할 수 있습니다.

class Fruit {
    private String name;

    Fruit(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    public String toString() {
        return "Fruit 이름:"+name;
    }
}
Fruit fruit = new Fruit("사과");

// System.out.println 메서드는 인자가 인스턴스인경우
// 내부적으로 toString() 메서드를 호출합니다.

System.out.println(fruit);
// Fruit 이름:사과

hashcode()

hashcode() 메서드는 객체의 hashcode를 반환하는 메서드입니다. hashcode() 메서드는 자바 가상머신에서 특정한 알고리즘을 이용하여 산술한 값을 반환합니다.

Fruit fruit = new Fruit("사과");

System.out.println(fruit.hashCode()); 

// 1627674070

hashcode는 주로 해시 테이블의 데이터 구조에서 저장과 검색을 하는데 사용됩니다.

hashcode를 재정의 할 경우 다음과 같은 의미가 되어야 합니다.

 

  1. hashcode가 같다는 것은 객체의 의미가 같다.
  2. 객체의 의미가 같으면 hashcode도 같다.
  3. hashcode가 다르다는 것은 객체의 의미가 다르다.
  4. 객체의 의미가 다르면 hashcode도 다르다.

equals(obj)

equals(obj) 메서드는 두 객체가 같은 경우 true를 반환하는 메서드입니다. 여기서 객체라는 의미는 인스턴스 일 수도 있고 동일한 의미의 객체일 수도 있습니다.

 

기존의 equals 메서드 내용

public boolean equals(Object obj) {
    return (this == obj);
}

 equals(obj) 메서드는 재정의 하지 않는 경우 기본적으로 == 연산자를 통하여 인스턴스가 같은지 파악합니다.

== 연산자는 인스턴스 메모리 주소를 비교하기 때문에 동일한 의미의 객체가 있다 하더라도 false 값을 반환할 수 있습니다.

 

두 인스턴스는 객체로서의 의미는 동일할 수 있으나 같은 인스턴스는 아니다

class Fruit {
    private String name;

    Fruit(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }
}
Fruit fruit1 = new Fruit("사과");
Fruit fruit2 = new Fruit("사과");

System.out.println(fruit1.equals(fruit2)); 
// false

객체의 내용은 동일하나 다른 메모리공간에 인스턴스가 적재되어있기 때문에 false 값을 반환합니다.

그러므로 동일한 객체라는 의미를 부여하기 위해서는 equals(obj) 메서드는 재정의해야 합니다.

 

equals 메서드 재정의

class Fruit {
    private String name;

    Fruit(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    // equals 메서드 재정의
    public boolean equals(Object obj) {
        if (obj instanceof Fruit) {
            Fruit tempFruit = (Fruit)obj;
            return name.equals(tempFruit.name);
        }
    }
}
Fruit fruit1 = new Fruit(“사과”);
Fruit fruit2 = new Fruit(“사과”);

System.out.println(fruit1.equals(fruit2)); 
// true

또한 equals(obj) 메서드를 재정의 하면 hashcode() 메서드도 재정의 해야 합니다. 스펙상 권장하는 부분입니다.

class Fruit {
    private String name;

    Fruit(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    // equals 메서드 재정의
    public boolean equals(Object obj) {
        if (obj instanceof Fruit) {
            Fruit tempFruit = (Fruit)obj;
            return name.equals(tempFruit.getName());
        }
        return false;
    }

    // hashCode 메서드 재정의
    public int hashCode() {
        int salt = 7;
        return 31 * salt * name.hashCode();
    }
}

[심화] equals 메서드를 재정의 하는 규칙

 

 

 

 

 

 

 

 

 

출처 : https://www.codelatte.io/courses/java_programming_basic/6SV594GBY4V2GY1X

'JAVA' 카테고리의 다른 글

[JAVA]예외처리  (0) 2023.11.10
[JAVA]null  (0) 2023.11.09
[JAVA]람다 표현식  (2) 2023.10.31
[JAVA]익명 클래스  (0) 2023.10.31
[JAVA]추상클래스와 인터페이스  (0) 2023.10.25