기본형(Primitive Type)
참조형(Reference Type)
참조형에서 형변환은 단순히 메모리의 크기만 고려하는 것이 아닌 클래스를 구성하는 구성 요소, 즉 구조가 같아야 한다.
일반 클래스 간에 형변환은 원칙적으로 할 수 없다.
단, 상속 관계에 있는 클래스 간에는 형변환을 할 수 있다.
클래스간의 형변환은 두 가지 방식이 있는데, 업캐스팅과 다운캐스팅이다.
// Parent parent 는 상위 클래스형 참조 변수
// new Child() 는 하위 클래스 객체
Parent parent = new Child();
// 상위 클래스 = 하위 클래스
// 상위 클래스로 형변환
하위 클래스인 Child 객체를 만들면 상위 클래스인 Parent 클래스로부터 상속받은 영역과 Child 클래스에서 확장한 영역으로 메모리에 할당이 일어난다.
하지만 Child 클래스에서 확장한 영역으로 할당된 메모리는 은닉(가려짐)된다. 즉 하위 클래스에 접근 권한이 사라진다.
자바에서는 업캐스팅만을 지원한다.
컴파일러에 의해서 자동으로 형변환이 일어난다.
업캐스팅 된 후에는 상위 클래스로부터 상속받은 메서드만 호출 가능하고 하위 클래스의 메서드는 사용할 수 없다.
단, 재정의된 메서드는 업캐스팅이 되면 오히려 상위 클래스로부터 상속받은 메서드가 은닉되고, 하위 클래스에서 재정의된 메서드를 참조할 수 있다.
왜냐하면 컴파일 중에 결정된 클래스형이 아닌 실행 중에 생성된 객체의 클래스형에 의해 호출될 메서드가 결정되기 때문이다. 이를 동적 바인딩이라고 한다.
Parent parent = new Child(); // 업캐스팅
Child child = (Child) parent;
처음 업캐스팅이 일어나고서 하위 클래스인 Child의 객체에는 상위 클래스로부터 상속받은 메모리뿐만 아니라 하위 클래스에서 확장한 메모리도 받는다. 단, 하위 클래스에서 확장한 메서드나 속성은 은닉되어서 사용할 수 없다.
이 때, 상위 클래스형의 참조 변수인 parent를 다시 하위 클래스형인 Child로 변환하면 은닉된 하위 클래스의 메서드와 속성에 접근할 수 있다.
Java에서는 원칙적으로 다운캐스팅을 허용하지 않지만, 이렇게 업캐스팅한 후에 다시 다운캐스팅하는 상황에 있어서는 형변환을 허용한다.
단, 명시적으로 강제로 cast 연산자를 사용해서 형변환을 해야 한다.
기본형과 달리 참조형의 형변환은 원칙적으로 지원하지 않는다.
단, 상속 관계에 있는 클래스 간에 형변환은 지원한다.
업캐스팅(상위 클래스형으로 형변환)은 자동으로 이루어진다.
다운캐스팅(하위 클래스형으로 형변환)은 업캐스팅을 했다가 다시 다운캐스팅할 때만 cast 연산자를 통해 명시적으로 형변환할 때만 가능하다.