오늘은 참조자료형의 형변환에 대해서 정리해 보겠다.
사실 블로그 정리 전까지 아리송 까리송 했는데, 이제야 개념 확립이 된거 같아 정리.....
다음 코드를 보자
1
2
3
4
5
6
7
8
|
package c;
public class ParentCasting {
public ParentCasting() {}
public ParentCasting(String name){}
public void printName(){
System.out.println("print Parent!!!");
}
}
| cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
package c;
public class ChildCasting extends ParentCasting {
public ChildCasting(){}
public ChildCasting(String name){}
public void printName() {
System.out.println("print Child!!");
}
public void printHobby(String hobby) {
System.out.println("My hobby is "+hobby);
}
}
| cs |
위와 같이 부모와 자식의 객체가 상속 받고 있다고 하자.
다음과 같이 일반적으로 쓸 수 있을 것이다.
ParentCasting parent = new ParentCasting();
ChildCasting child = new ChildCasting();
위와 같이 하면 컴파일에 아무 지장이 없다. 그럼 어디서 많이 봐왔던? 다음 코드
ParentCasting obj = new ChildCasting();
위 코드는 상속 관계가 성립하고, 자식의 생성자로 부모 인스턴스를 만들 수 있다.
책 어디서 봐 왔던 형 변환이 필요 없는 방법이다.
(부모 입장에서 호출할 수 있는 메서드는 자식에서도 사용할 수 있으므로)
하지만 다음 코드는 에러를 내 뿜는다.
ChildCasting obj2 = new ParentCasting();
자식은 확장된 코드가 필요한데 좁아터진 부모 객체를 대입하려 했기 때문.
책 등에서는 위와 같이 표현을 하곤 하는데 나는 잘 이해가 가지 않았다.
그래서 메모리 구조를 그려 보았다.
메모리 구조인데 간단하게 설명하자면 스택엔 클래스의 인스턴스 정보가 힙에는 클래스의 객체 정보가 들어간다고 생각하면 된다.
위에서 보는 것처럼 obj2는 ParentCasting 객체를 가지고 있다. ParentCasting은 printName() 메서드 하나만 가지고 있고, ChildCasting은 printName()과 printHobby() 메서드 2개를 가지고 있으니 ChildCasting 입장에선 불만?인게 되어 에러가 발생하는 것이다.
그럼 형변환 해주면 되지 않나??
ParentCasting obj = (ChildCasting)parent;
위와 같이 하면 컴파일 에러는 안난다. 근데, 실행시 예외가 발생한다.
근데 예외가 안날 수도 있다.(장난하늬??)
자식 객체에서 부모 객체를 그대로 쓰면(확장을 안하면) 위와 같이 쓸 수 있다.
아니 그럼 어떻게 해야 하늬??
다음과 같이 하면 에러 없이 잘 수행 된다.
ChildCasting child = new ChildCasting();
ParentCasting parent = child;
ChildCasting child2 = (ChildCasting)parent;
무엇이 다른지 유심히 보자. 위의 parent객체는 겉모습은 ParnetCasting이지만 알맹이는 ChildCasting이니 형변환해도 문제가 없다.(이해안가면 메모리구조를...)
여기 까지 형변환에 대해서 알아 보았다. 메모리 구조를 그려가며 생각하니 이제서야 이해가 가는것 같다.
그럼 끝~!
댓글
댓글 쓰기