public class Child {
}
public class review {
public static void main(String[] args) {
Child child = new Child();
String string = child.toString();.
System.out.println(string);
}
}
출력값
Child@b4c966a // @앞은 클래스명 @뒤는 문자열(String)형 참조값
new Child로 Child 객체를 생성하였다.
Child 객체는 상속 받는 객체가 없으므로 Object 클래스를 상속 받는다.
자식 객체를 생성하면 부모 객체 정보도 같이 분리되어 생성된다.
Child 클래스엔 toString() 메서드가 없다.
main()메서드에서 child.toString() 메서드를 호출 하였다.
child 클래스에서 해당 메서드가 없으니 부모 클래스에서 해당 메서드를 찾는다.
Object클래스에서 toString() 메서드가 발견되어 출력이 되었다.
*자식 객체가 생성되며 부모 객체 정보도 분리되어 같이 생성되니 Object obj = new Object(); 와 같은 객체 생성 필요 없이 toString() 메서드가 호출이 가능하다.
public class Dog {
public void sound() {
System.out.println("멍멍")
}
}
public class Car {
public void move() {
System.out.println("차 지나가유")
}
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
Car car = new Car();
action(dog);
action(car);
}
public static void action(Object obj) {
//Object obj = dog; //부모는 자식을 품을 수 있다.
if(obj instanceof Dog dog) {
//obj 다운캐스팅. Dog dog 가 obj의 인스턴스가 맞다면
dog.sound();
} else if(obj instanceof Car car) {
//obj 다운캐스팅. Car car 가 obj의 인스턴스가 맞다면
car.sound();
}
}
}
위와 같이 Object는 Dog도 참조하고 Car도 참조하였다.
하지만 Object에 없는 메서드를 호출하기 위해선(오버라이딩도 안뎀) 다운캐스팅이 필요하다는 한계가 있다.
배열도 동일하게 모든 객체를 담을 수 있다.
Object.toString() (클래스로 직접 접근하는거 보니 static 메서드인가?) 는 객체의 정보를 문자열의 형태로 제공한다고 하였다.
잠깐 예제를 보자.
public class Main {
public static void main(String[] args) {
Object object = new Object();
String string = object.toString();
//toString() 반환값 출력
System.out.println(string);
//출력값 : java.lang.Object@10f87f48
System.out.println(object);
//출력값 : java.lang.Object@10f87f48 @ 앞은 클래스 위치, @ 뒤는 참조값.
}
}
?! object.toString()을 값을 담은 string의 출력값과 Object 객체 생성의 값을 담은 object의 출력값이 같다.
사실 System.out.println() 메서드는 내부에서 toString()을 호출한다.
즉, Object 타입(자식 포함)이 println() 메서드에 인수로 전달 되면 println() 메서드 내부에서 Object.toString()을 호출한다.
즉즉, 우리가 println(객체)를 통해 참조값을 얻은 건 사실 println(객체.toString())에서 .toString()이 생략된 것이였던 것!!!!
Object 클래스에서 toString()메서드가 있다는 것을 알았다.
Object 클래스는 모든 객체의 최상위 부모 이므로
자식 클래스에서 toString()메서드를 재정의(오버라이딩)하는 것이 물론 가능하다.
자식 클래스에서 toString()메서드를 오버라이딩 했으니 외부에서 toString()메서드를 호출할 경우 오버라이딩 된 toString()이 호출된다.
(오버라이딩 메서드는 최우선권을 가진다.)
그렇다면 println()을 하게 되면 어떻게 될까????앙???
println() 메서드 내부에서 toString()메서드를 호출한다고 하였다.
toString()메서드를 오버라이딩 하였으니, 당연히 println()도 오버라이딩된 toString()메서드를 반환한다.
(오버라이딩된 toString()의 값 말고 원래 toString()의 값을 보고 싶다? -> String refValue = Interger.toHexString(System.identityHashCode(객체)); 를 하면 뎀.)