[Java]자바 기본 클래스 - Object 클래스

나영원·2020년 8월 30일
0

Java_basic

목록 보기
53/60
post-custom-banner

Object 클래스

Object 클래스는 모든 클래스이 최상위 클래스로 모든 클래스는 Object 클래스에서 상속을 받습니다. 그렇기 때문에 모든 클래스는 Object클래스의 메서드를 사용 가능하고 그 중 일부는 재정의 하여 사용할 수 있습니다. 위치는 java.lang.Object 클래스 입니다.

ToString 예제

class Book{
	String title;
	String author;
	
	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}

	@Override
	public String toString() {
		return author + "," +title;
	}
	
	
}
public class ToString {
	
	public static void main(String[] args) {
		
		Book book = new Book("토지", "박경리");
		
		System.out.println(book);
		
		String str = new String("토지");
		System.out.println(str.toString());
	}
}
  • Object클래스의 메서드인 ToString를 예제로 사용해보겠습니다. ToString 클래스를 만들면 모든 클래스는 Object를 상속하기 때문에 ToString클래스 또한 Object에 메서드를 사용할 수 있습니다.

  • 이후 Book클래스를 작성하여 인스턴스를 생성시 title과 author입력할 수 있게 한후 다시 main메서드로 돌아와 Book인스턴스를 생성하여 "토지", "박경리"를 입력합니다.

  • 그후 출력문으로 book을 출력하면 내용물이 출력되는 것이아닌 인스턴스의 주소값이 출력됩니다.

  • 하지만 String인스턴스를 생성하여 입력하여 str을 출력하면 바로 토지가 출력이되는데 그것은 String이 출력될때 자동으로 toStirng 메서드를 사용하게 되어있기 때문입니다.

  • Book에서도 자동으로 toString()을 하기 위해 Book 클래스에 toSTring메서드를 재정의하고 author + "," title순으로 출력되게 하고 다시 book을 출력해보면 "토지", "박경리'하고 출력되게 됩니다.

  • 이것을 통해서 모든클래스에서 Object클래스의 메서드를 사용할 수 있고 또한 필요에 따라 메서드를 재정의해서 사용할 수 있는 것을 알 수 있었습니다.

equals() 메서드

equals()메서드는 두 객체의 동일함을 논리적으로 재정의하는 메서드입니다. 여기서 논리적 동일함은 서로 주소는 다르지만 같은 값을 가지는 객체를 뜻하고 서로 같은 주소를 가지는 물리적 동일함과 다른 의미로 사용됩니다. 정리해보면 equals()는 물리적으로 다른 메모리에 위치한 객체라도 논리적으로 동일함을 구현하기 위해 사용되는 메서드입니다.

public class EqualsTest {

	public static void main(String[] args) {
		
		String str1 = new String("abc");
		String str2 = new String("abc");
		
		System.out.println(str1==str2);//false
		System.out.println(str1.equals(str2));//true
	}

str1==str2 에서 ==은 주소값이 동일한지 물어보는 것임으로 물리적동일함을 묻는 것이고 두 인스턴스는 다른 주소에 있기 때문에 false가 반환됩니다.
stra.equals(str2)는 논리적 동일성을 묻고 있기 때문에 두인스턴의 값은 abc로 같기에 true가 반환됩니다.

class Student{
	int studentNum;
	String studentName;
	
	public Student(int studentNum, String studentName) {
		this.studentNum=studentNum;
		this.studentName=studentName;
	}

	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Student) {
			Student std = (Student)obj; //Object클래스로 업캐스팅된걸 다운캐스팅
			return (this.studentNum == std.studentNum);
		}
		return false;
	}
	
}
public class EqualsTest {

	public static void main(String[] args) {
		
	Student Lee = new Student(100, "이순신");
	Student Lee2 = Lee;
	Student shin = new Student(100, "이순신");
	
	System.out.println(Lee == Lee2); //true
	System.out.println(Lee == shin); //false
	System.out.println(Lee.equals(shin)); //재정의전//false
	System.out.println(Lee.equals(shin)); //재정의후//true
	
	}
}
  • Lee와 Lee2는 물리적으로 같은 주소를 가지고 있기 때문에 Lee=Lee2는 true가 반환됩니다.

  • Lee와 shin는 물리적으로 같지 않기 때문에 Lee == shin 는false가 반환됩니다.

  • Lee.equals(shin) equlas 재정의 전에는 비교할 항목이 지정이 안되있기 때문에 false가 발생합니다
    Book 클래스로 돌아가서 equals 메서드를 재정의합니다. 메서드에서 사용될 때 비교되는 항목이 자동으로
    Object로 업캐스팅 되기 때문에 instanceof를 사용해서 안전하게 Student클래스로 다시 다운캐스팅하고 두 항목의 studentNum을 비교하게 재정의합니다

  • 다시 Lee.equals(shin)을 하게되면 true가 반환됩니다.

hashCode() 메서드

hashCode() 메서드의 반환값은 10진수의 인스턴스가 저장된 가상머신의 주소입니다.

	System.out.println(Lee); //object.Student@79fc0f2f
	System.out.println(Lee.hashCode()); // 2046562095
	System.out.println(shin.hashCode()); // 1342443276
  • 기본 주소값이 16진수인 것과 다르게 hashCode()를 사용하면 10진수 주소를 반환해 줍니다.

  • 두개의 서로 다른 메모리의 위치한 인스턴스가 동일하다는 것은 equals()의 반환값이 true여서 논리적인 동일함을 보여주고 또한 동일한 hashCode값을 가져야 합니다.

  • 위의 Lee와 Shin은 equals()의 반환값은 true이지만 hashCode의 값은 다른 모습을 보여주고 있는데 이는 hashCode는 재정의 하지 않았기 때문입니다. 이러한 이유로 equals()를 재정의할 때 hashCode()를 같이 재정의해주는 경우가 많습니다.

  • 참고로 hashCode가 같아 지게 재정의한다고해서 실제 hashCode 주소값이 같다는 뜻은 아닙니다.

	//Book 클래스
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Student) {
			Student std = (Student)obj; //Object클래스로 업캐스팅된걸 다운캐스팅
			return (this.studentNum == std.studentNum);
		}
		return false;
	}
    @Override
	public int hashCode() {
		return studentNum;
	}
    //main 메서드
    System.out.println(Lee.hashCode()); // 100
	System.out.println(shin.hashCode()); // 100
    
    System.out.println(System.identityHashCode(Lee)); //2046562095
	System.out.println(System.identityHashCode(shin)); //1342443276	
  • hashCode를 재정의하여 Lee와 shin에 hashCode()를 같게 만드려고 할 때 return값은 equals를 재정의 할대 썻던 멤버 변수를 사용하는게 좋습니다.

  • 그래서 return을 equals에서 기준이 되었던 studentNum을 사용하면 Lee와 shin의 hashCode()값이 100으로 같아지는 것을 확인할 수 있습니다.

  • 만약 진짜 hascode()값이 궁금하다면 System.identityHashCode()메서드를 사용하며 됩니다.

clone()메서드

-clone() 메서드는 객체의 복사본을 만드는 메서드로 기본틀(prototype)이 되는 객체로부터 같은 속성 값을 가진 복사본을 생성할 수 있는 메서드입니다.

-객체지향 프로그래밍의 정보은닉에 위배되는 가능성이 있으므로 복체할 객체는 clonable 인터페이스를 명시해야 합니다.

class Book implements Cloneable{
	String title;
	String author;
	
	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}

	@Override
	public String toString() {
		return author + "," +title;
	}
	//클론 매서드
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}

클론메서드를 추가하기 위해 클래스 선언부에 복사가 가능하다는 의미로 implements Clonable을 붙여줍니다.
클론 메서드를 재정의하는데 따로 수정할 것은 없고 그대로 가져다 쓰면됩니다.

public class ToString {
	
	public static void main(String[] args) throws CloneNotSupportedException {
		
		Book book = new Book("토지", "박경리");
		
		System.out.println(book); // 박경리,토지
		
		Book book2 = (Book)book.clone();
		
		System.out.println(book2); // 박경리,토지	
	}
}
  • book의 복사본을 만들기 위해 book2에 book.clone()메서드를 사용해주고 앞에 (Book)타입을 명시해 줍니다.

  • 예외 처리를 하고 book2를 출력해보면 book과 같은 결과값을 얻을 수 있습니다.

profile
배우는 개발 일기
post-custom-banner

0개의 댓글