언어/JAVA

[JAVA] Object 클래스

hvoon 2022. 9. 8. 09:54

-사용자 정의 클래스를 생성하면서, extends(상속)을 구현하지 않으면 자동으로 java.lang.Object 클래스를 상속.
-Object 클래스는 Java 에서 사용되는 모든 클래스들의 최상위 부모클래스
-Subclass extends Super  라는 건  Subclass 는 Object 클래스를 상속하지 않지만 Super 클래스가 Object 클래스를 상속하므로,  Subclass 는 Object 클래스를 상위의 상위로 상속한것과 같은 의미

class UserClass {
}

public class Extends09_Object01 {
	public static void main(String[] args) {
		UserClass obj = new UserClass();
		// getClass 메소드는 해당 객체의 클래스 이름을 리턴해주는 메서드이며,
		// Object  클래스에서 상속 받은 메서드
		System.out.println( obj.getClass() );
		
		// hashCode 메소드는 해당 객체의 해시코드값(다른객체와 구분하기위한 고유값)을
		// 리턴해주는 메서드(JVM에 의해서 관리되고 있는 번호)
		System.out.println( obj.hashCode() );
		
		// toString 메소드는 해당 객체의 정보를 문자열로 리턴해주는 메서드
		System.out.println( obj.toString() );
		// 객체의 클래스명 + '@' + 해시코드값(16진수)
		
		System.out.println( obj ); 
		//System.out.println(obj.toString()); 와 같음
	}
}

 

toString 메소드의 사용
-toString 메소드는 클래스의 객체 정보를 문자열로 반환 : 
-객체의 클래스명 + '@' + 해시코드값(16진수)
-사용자 정의 클래스(직접 개발한 클래스)에 toString 메소드를 오버라이딩하여 클래스의 정보를 문자열로 제공하도록 변형(재정의) 가능

class UserClassB {  // toString 메서드를 오버라이딩 하지 않은 클래스
}

class Point { // toString 메서드를 오버라이딩한 클래스
	private int x;
	private int y;
	public Point(int x, int y) {this.x = x; this.y = y;}
	public String toString() {
		return "(x=" + this.x + ",  y=" + this.y + ")"; 
		// "x = 값, y = 값" 리턴
	}
}

public class Extends09_Object02 {
	public static void main(String[] args) {
		UserClassB obj1 = new UserClassB();
		UserClassB obj2 = new UserClassB();
		System.out.println("오버라이딩 되지 않은 toString() => " + obj1.toString());
		System.out.println("오버라이딩 되지 않은 toString() => " + obj2);
		
		Point p = new Point(30,20);
		System.out.println("오버라이딩 된 toString() => " + p.toString());
		
		// .toString() 은 print 에서 사용되거나 다른 문자열과 '+' 연산될 때 생략 가능
		// System.out.println("오버라이딩 된 toString()=>" + p);
		String msg = "Point => " + p;  //String msg = "Point => " + p.toString();
		System.out.println(msg);
	}

}

 

Object 클래스의 equals 메소드

-객체간의 비교를 위해서 사용되는 메서드
-Object 가 상속한 메서드들 중 toString과 함꼐 가장 많이 오버라이딩 되는 메서드

public class Extends09_Object03 {
	public static void main(String[] args) {
		
		// 일반적, 기본 자료형들의 갑의 비교는 비교연산자(==)를 사용
		int n1 = 10;
		int n2 = 10;		
		if( n1 == n2 )	System.out.println("n1 변수와 n2 변수는 같습니다.");
		else 	System.out.println("n1 변수와 n2 변수는 다릅니다.");
		
		String s1 = "Hello";
		String s2 = "Hello";
		if( s1 == s2 )	System.out.println("s1 변수와 s2 변수는 같습니다.");
		else	System.out.println("s1 변수와 s2 변수는 다릅니다.");
		System.out.println(s1); // "Hello"출력 
		// 이미 String 클래스에는  저장된 문자가 리턴되는 toString() 메서드가 오버라이딩 되어 있음
		
		// ==  연산은 변수가 직접 저장한 값으로 비교해주는 연산자라는 것을 감안하면
		// s1==s2 는 두개의 참조변수값(주소값)이 비교되었다라는것을 알 수 있음
		// 현재의 s1 과 s2 는 같은 주소를 갖고 있다는 말이기도 함
		
		// String s1 = "Hello"; 실행시에 HEAP 영역에 Hello 가 저장되고 그 주소가 s1 변수에 저장
		// String s2 = "Hello"; 실행시에는 새로운 영역에 Hello 가 저장되는게 아니라
		// 이미 존재하는 Hello 의 주소를  s2 에 또 저장
		// 이는 모두 new  키워드가 없어서 새로운 공간이 안생겼기때문에 일어나는 현상
		// 물론 s1 = "world"; 라는 새로운 글자를 저장하면 s2는 그데로 있고 새로운 공간에
		// "world" 가 저장되고 그 주소를 s1이 저장하긴 함
		
		String s3 = new String("Hello");
		String s4 = new String("Hello");
		if( s3 == s4 )	System.out.println("s3 변수와 s4 변수는 같습니다.");
		else	System.out.println("s3 변수와 s4 변수는 다릅니다.");
		// 앞선 명령과 달리 이번엔 new  키워드를 사용하여 서로 다른 공간에  Hello 를
		// 저장하고 각각의 주소를 s3 와 s4 에 저장
		// 결국 (==) 이 연산자는 글자들의 비교가 아니라, 레퍼런스 주소들의 비교라는 의미
		
		// 실제 객체의 값을 비교하기 위한 equals 메소드를 사용하면 참조값이 서로 다른 
		// 객체의 실제 데이터를 비교하여 동일한 데이터를 가지고 있는지 확인 가능.
		if( s3.equals(s4) )
			System.out.println("s3 변수와 s4 변수는 같습니다.(equals)");
		else	
			System.out.println("s3 변수와 s4 변수는 다릅니다.(equals)");
		// Object 클래스에서 상속받은 equals 메서드를 사용한것이고, String 클래스에 맞게
		// 오버라이딩되어 있기때문에 글자끼지 비교
		// 오버라이딩 되기 전의 equals 도 참조값끼리 비교
		
		// 같은 패키지안의 다른 파일에 있는 클래스의 객체생성이 자유롭게 가능
		Point p1 = new Point(10, 20);
		Point p2 = new Point(10, 20);
		if( p1.equals(p2) )
			System.out.println("p1 변수와 p2 변수는 같습니다.(equals)");
		else	
			System.out.println("p1 변수와 p2 변수는 다릅니다.(equals)");
		// equals 를 오버라이딩 하지 않은 클래스의 객체간   equals 매서드 사용은
		// 참조값들끼리 비교하는 결과를 얻음
	}

}

 

class Human{
	private String name;
	private int age;
	public Human(String name, int age) {	
		this.name = name;	this.age = age;
	}
	public String toString() {
		String info = "name = " + this.name + ", ";
		info += "age = " + this.age;   
		return info;  // "name = 홍길동, age=26"
	}
	
	//  s1.equals(s2)      this <- s1    obj<-s2
	public boolean equals( Object obj ) {
		
		// 매개변수로 Human 이 아닌 이상한 클래스의 객체가 왔으면 그냥 바로 return false (메서드 종료)
		if( !(obj instanceof Human) ) 
			return false;
		
		Human target = (Human)obj;
		boolean flag_name = this.name.equals(target.name);
		boolean flag_age = this.age == target.age;
		boolean result = flag_name && flag_age;
		return result;
	}
}

public class Extends09_Object04 {
	public static void main(String[] args) {
		Human s1 = new Human("홍길동", 21);
		Human s2 = new Human("홍길동", 21);
		Human s3 = new Human("홍길서", 22);
		System.out.println("Human1의 정보 : " + s1);
		System.out.println("Human2의 정보 : " + s2);
		System.out.println("Human3의 정보 : " + s3);
		
		if( s1 == s2 )	
			System.out.println("s1 변수와 s2 변수는 같습니다.(s1==s2)");
		else	
			System.out.println("s1 변수와 s2 변수는 다릅니다.(s1==s2)");
		
		if( s1.equals(s2) )	
			System.out.println("s1 변수와 s2 변수는 같습니다.(s1.equals(s2))");
		else	
			System.out.println("s1 변수와 s2 변수는 다릅니다.(s1.equals(s2))");
	}
}

 

Vector

-배열의 확장형구조(리스트)-객체들을 저장할 수 있는 배열
-사용자가 만든 클래스 객체의 레퍼런스값을 저장하는 다형성 객체 저장 리스트

import java.util.Vector;

//상품과 구매자를 클래스로 만들고 구매, 환불 등의 동작을 매서드로 제작
class Product{
	int price;
	int bonusPoint;  // 상품을 구매했을때 구매자에게 부여된 보너스 포인트
	// Product(){}
	Product(int p){
		this.price = p;
		this.bonusPoint = p/10;
	}
}

class Computer extends Product{
	Computer(){
		super(150);    
		// 부모클래스의 생성자가 디폴트가 아니면, 현재 있는 생성자에 맞춰서 호출해야함
	}
	public String toString() {
		return "Computer";
	}
}
class Tv  extends Product{
	Tv(){   super(100);  }
	public String toString() {  return "Tv";  }
}
class Audio  extends Product{
	Audio(){   super(60); }
	public String toString() {	  return "Audio"; 	} 
}

class Buyer{
	int money = 1000;    // 구매자가 소지한 금액
	int bonusPoint = 0;  // 물건을 구매해서 얻은 보너스포인트
	Vector item = new Vector();  // 구매목록
	// Computer c = new Computer();
	// item.add(c);
	
	//public void buy(Tv t) { item.add(t); }
	//public void buy(Computer c) { item.add(c);	}
	//public void buy(Audio a) { 	item.add(a); }
	
	// 부모클래스의 레퍼런스 변수에는 자식인스턴스의 주소를 저장할 수 있음 (자동 캐스팅)
	public void buy( Product p ) {
		// 부모클래스의 레퍼런스변수에 저장된 자식클래스 객체에서 물려준 멤버들,
        // 오버라이딩된 멤버들에 접근이 가능
		
		// 전달된 제품을 구매할정도의 잔액이 충분한가
		if( this.money < p.price ) {
			System.out.println("잔액이 부족합니다");
			return;
		}
		this.money -= p.price;
		// 제품의 bonusPoint 를 Buyer 의 bonusPoint 에 가산
		this.bonusPoint += p.bonusPoint;
		
		System.out.println( p + "을 구입하셨습니다" );
		// p(부모클래스의 레퍼런스 변수)로 오버라이딩된 toString()을 사용
		
		// 제품 객체를 item 리스트객체에 추가
		item.add(p);
		
		// Vector 클래스의 멤버메서드add 의 생김새  - 매개변수가 Object 형이어야 뭐든 전달 가능
		// public void add( Object obj ){ }
	}

	public void summary() {
		int sum = 0;    // 지출 총액 변수
		String itemList = "";   // 구매 목록 변수.	
		if( item.isEmpty() ) {
			// item.isEmpty() :Vector 객체인 item 이 비어 있으면 true 리턴하는 메서드
			System.out.println("구입하신 제품이 없습니다");
			return;
		}
		for( int i=0; i<item.size(); i++) {
			// item.size() : 저장된 요소의 갯수 리턴합니다
			
			// item 에 저장됬던 걸 읽어내서 Product 형 변수에 담음
			Product p = (Product)item.get(i);
			// 부모레퍼런스변수에 저장됬던 자식인스턴스의 주소값이, 다시 자식레퍼런스에 
			// 전달되려면 강제 캐스팅이 필요
			sum += p.price;   // 구입금액 합산
			itemList = itemList + p + "  " ;   // 구매상품이름 이어붙임
		}
		System.out.println("지출총액 : " + sum + ",     구매목록 : " + itemList);
		// Product p = (Product)item.get(i);  
        // get메서드는 꺼내고 지우고동작이 아니라 읽어내는 동작. 
        // 따라서 get이 실행된다고 리스트에서 지워지는건 아님
	}

	public void refund( Product p ) {
		// item.remove(p) : item에서 p를 삭제 - 참조값(주소)로 검색해서 삭제
		// 삭제가 잘 되었다면 true 를 리턴해주는 메서드
		if( item.remove(p) ) {
			// buyer 잔액에   상품 가격 합산
			money += p.price;
			// 보너스 포인트 차감
			bonusPoint -= p.bonusPoint;
			// 환불 상품안내  "~~를 반품하셨습니다"
			System.out.println(p + "을/를 반품하셨습니다.");
		}else {
			System.out.println("구입하신 물품중에 해당 제품이 없습니다");
		}
	}
}

public class Extends09_Object05 {
	public static void main(String[] args) {
		Tv t = new Tv();
		Computer c = new Computer();
		Audio a = new Audio();
		
		System.out.println(t);  // toString() 메서드가 오버라이딩되면, 생략해도 호출됨
		System.out.println(c);
		System.out.println(a);
		
		Buyer b = new Buyer();
		b.buy(c);  
		b.buy(a);   
		b.buy(t);
		
		b.summary();
		
		b.refund(c);
		b.summary();
	}
}