타입 변환은 타입을 다른 타입으로 변환시키는 것이다.
서로 상속관계에 있다면 자식 클래스는 부모 클래스로 자동 타입 변환이 가능하다.
Animal과 Cat이 상속관계에 있다고 가정해보자.
class Animal{...}
class Cat extends Animal{...}
Cat 클래스에서 Cat 객체를 생성하고 이것을 Animal 변수에 대입하면 자동 타입 변환이 일어난다.
Cat cat = new Cat();
Animal animal = cat;
//Animal animal = new Cat(); 처럼 한 줄로 줄일 수도 있다.
이렇게 표현한 코드로 생성되는 메모리 상태는 cat과 animal 변수는 타입만 다를 뿐, 동일한 Cat 객체를 참조하게 된다.

그림에서 animal 변수가 Animal 타입이니까 당연히 부모인 Animal 객체를 참조하는게 맞는거 아니냐?
라고 생각할 수 있지만, 아래 코드를 작성해보면 둘이 같은 번지를 참조하는 것을 알 수 있다.
cat == animal; //true
cat과 animal이 true가 나온다는 말은 참조 번지가 같다는 말이므로, 두 변수가 같은 객체를 참조하고 있다할 수 있다.
바로 위의 부모가 아니어도 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있다.
class A{}
class B extends A{}
class C extends A{}
class D extends B{}
class E extends C{}
public class PromotionEx{
public static void main(String[] args){
B b = new B();
C c = new C();
D d = new D();
E e = new E();
A a1 = b;
A a2 = c;
A a3 = d;
A a4 = e;
B b1 = d;
C c1 = e;
// 아래 두 코드는 상속관계에 있지 않아 컴파일 에러다.
B b2 = e;
C c2 = d;
}
}
위의 코드를 그림관계로 나타내면 아래와 같다.

이처럼 서로 상속관계에 있는 B와 D는 자동 타입 변환이 가능하지만, E를 B로, D를 C로 타입 변환하는 것은 서로 상속관계에 있지 않아 불가능하다.
부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능하다.
변수는 자식 객체를 참조하지만, 변수로 접근 가능한 멤버는 부모 클래스 멤버로 한정된다.
예외 사항으로, 메소드가 자식 클래스에서 재정의 되었다면, 자식 클래스의 메소드가 대신 호출된다.
class Parent{
void method1() {...}
void method2() {...}
}
class Child extends Parent{
@Override
void method2() {...}
void method3() {...}
}
class ChildEx {
public static void main(String[] args){
Child child = new Child();
Parent parent = child;
parent method1(); //Parent
parent method2(); //Child
parent method3(); //컴파일 에러
}
}
위의 코드에서 Child 객체는 method3() 메소드를 가지고 있지만, Parent 타입으로 변환된 이후에는 method3()를 호출할 수 없다.
하지만 method2()는 Parent와 Child 둘 다 가지고 있기 때문에, 오버라이딩 된 메소드는 타입 변환 이후에 자식 메소드로 호출이 된다.
'백엔드 공부 > Java' 카테고리의 다른 글
| [Spring] Test코드 실행 시 NullPointerException 발생 (0) | 2024.03.18 |
|---|---|
| [Java] ArrayList와 LinkedList (2) | 2023.12.27 |
| [Java] static? (4) | 2023.11.27 |
| [Java] 열거 타입 (0) | 2023.11.24 |
| [Java] 향상된 for문 (2) | 2023.11.24 |