☕ JAVA

[📖JAVA]자바 다형성① 다형적 참조➰(업캐스팅, 다운캐스팅)

도하빵 2024. 9. 10. 08:00

다형성은 이름 그대로 다양한 형태, 여러 형태를 의미합니다.
다형성을 이해하기 위해서는 크게 다형적 참조와 메서드 오버라이딩 두 가지를 알아야 하는데요.
이번 시간에는 다형성 참조에 대해 자세히 공부해보는 시간을 가져보겠습니다.

 

1️⃣ 다형적 참조

`Parent parent = new Parent();`
아래의 코드는 `Parent`라는 클래스를 사용해서 `parent`라는 이름의 객체를 만들고 있습니다.
여기서 Parent 클래스를 이용해 객체를 만들었으니까 당연히 메모리에도 Parent 객체만 생성됩니다.

즉, 이 코드로는 자식 클래스인 Child는 생성되지 않고, 오직 Parent 객체만 만들어집니다.
이 객체를 생성한 후, 그 객체의 참조값을 parent라는 변수에 저장합니다.

 

 부모 클래스

public class Parent {
    public void parentMethod(){
        System.out.println("Parent.parentMethod");
    }
}

 

자식 클래스

public class Child extends Parent{
    public void childMethod(){
        System.out.println("Child.method");
    }
}

 

📎 인스턴스 생성 예제

⭐ 부모는 자식을 품을 수 있다.
◾부모 타입 변수에 자식 객체 참조 가능
`Parent poly = new Child();`
✔️ poly는 Parent 타입의 변수로 선언되어 있습니다.
✔️ 실제로 poly가 참조하는 객체는 Child 타입입니다.

이 경우 poly를 통해 호출할 수 있는 메서드는 Parent 클래스에서 정의된 것만 사용할 수 있습니다. Child 클래스에서 추가된 메서드나 속성은 사용할 수 없습니다.

◾자식 타입 변수에 부모 객체 참조 불가능
`Child poly = new Parent();`
Child 타입의 변수는 Parent 타입의 객체를 참조할 수 없습니다.(컴파일 오류)
자식 클래스는 부모 클래스의 인스턴스를 담을 수 없기 때문입니다.

 

public class PolyMain {
    public static void main(String[] args) {
        // 부모 변수가 부모 인스턴스 참조
        System.out.println("Parent -> Parent");
        Parent parent = new Parent();
        parent.parentMethod();

        // 자식 변수가 자식 인스턴스 참조
        System.out.println("Child -> Child");
        Child child= new Child();
        child.childMethod();

        // 부모 변수가 자식 인스턴스 참조(다형적 참조)
        System.out.println("Parent -> Child");
        Parent poly = new Child();
        poly.parentMethod();
    }
}

2️⃣ 다운캐스팅

위의 문제를 해결할 방법으로는 다운캐스팅이 있습니다.
poly가 참조하는 객체의 타입을 Child로 변환하는 과정인데요.

public class CastingMain1 {
    public static void main(String[] args) {
        // 부모 변수가 자식 객체를 참조
        Parent poly = new Child(); // x001

        // 다운캐스팅을 통해 Child 타입으로 변환
        Child child = (Child) poly; // x001
        child.childMethod(); // Child 클래스에서 추가된 메서드 사용

        // 일시적 다운캐스팅 - 해당 메서드를 호출하는 순간만 다운캐스팅
        ((Child) poly).childMethod();
    }
}

 

🚨 주의할 점

캐스팅을 한다고해서 Parent poly 의 타입이 변하는 것이 아닙니다.
poly 변수의 타입은 여전히 Parent로 남아 있지만,

child라는 새로운 변수를 통해 Child 타입의 기능을 사용할 수 있게 됩니다.
따라서 poly의 타입은 Parent로 기존과 같이 유지되는 것입니다.

3️⃣ 업캐스팅

public class CastingMain4 {
    public static void main(String[] args) {
        Child child = new Child();
        Parent parent1 = child; // 업캐스팅
        Child child1 = (Child)parent1;
        child1.childMethod();

        Parent parent2 = new Parent();
        Child child2 = (Child)parent2;  // 런타임 오류, Parent 객체 생성시에는 자식 메모리는 생성되지 않는다.
        child2.childMethod();
    }
}

📁 다운캐스팅과 업캐스팅의 차이


상위로 올라가는 업캐스팅은 인스턴스 내부에 부모가 모두 생성되기 때문에 문제가 발생하지 않는 반면,
객체를 생성할 때 하위 자식은 생성되지 않기 때문에 하위로 내려가는 다운 캐스팅은 인스턴스 내부에 없는 부분을 선택하는 문제가 발생할 수 있다.

◾업캐스팅 
A a = new C() : A로 업캐스팅
B b = new C() : B로 업캐스팅
C c = new C() : 자신과 같은 타입

◾다운캐스팅
A a = new B() A로 업캐스팅
B b = new B() 자신과 같은 타입
C c = new B() 하위 타입은 대입할 수 없음(컴파일 오류) 👉 자식은 부모를 담을 수 없음
C c = (C) new B() : 하위 타입으로 강제 다운 캐스팅(B 인스턴스에 C가 없으므로 런타임 오류 발생)

728x90
320x100