[Java] 형변환(casting), 업캐스팅(upcasting) & 다운캐스팅(downcasting)

haeun_06·2023년 4월 22일
1

JAVA

목록 보기
3/8
post-thumbnail

0422

업캐스팅(upcasting)과 다운캐스팅(downcasting)을 이해해보자!

요즘 시험기간이라 업캐스팅, 다운캐스팅을 공부하고 있는데 이해가 도저히 안 되는 거에요,,

그래서 제가 이해하고자, 또 다른 사람들에게 더 쉽게 알려주고자 업캐스팅과 다운캐스팅에 관련하여 글을 쓰려 합니다!



Casting(형변환)이란?

업캐스팅과 다운캐스팅 모두에 들어있는 바로 이 Casting은 무엇일까요?

캐스팅은 데이터 타입이 다른 경우에 하나의 데이터 타입으로 통일해주기 위해 사용합니다.

정수와 실수를 더하려면 두 변수의 데이터 타입이 같아야 하는 경우에 사용이 되겠죠?


캐스팅에는 총 두 가지의 종류가 있습니다.

  • 자동형변환
  • 명시적형변환

자동형변환

프로그래머의 명시적인 요청 없이 컴파일러가 자동으로 타입을 변환하는 것

자동형변환이 일어나는 경우에는 작은 범위의 데이터타입에서 큰 범위의 데이터 타입으로 변환하는 경우에 발생하게 됩니다.

int i = 10;
double d = 3.14;
double result = d + i; // i가 자동으로 실수형으로 변환됨

위와 같이 int타입을 double타입으로 변환할 때 자동적으로 사용되겠죠.


명시적형변환

프로그래머가 직접 타입을 변환하는 것

명시적형변환은 큰 범위의 데이터타입을 작은 범위의 데이터타입으로 강제적으로 형변환할 때 사용하게 됩니다.

자신보다 작은 곳에 자신을 맞춰야 하므로 손실이 생길 수 있으며, 꼭 ()를 사용하여 강제형변환을 할 타입을 적어주어야 합니다.

int i = 10;
double d = (double)i;

이후 우리가 알아볼 업캐스팅은 자동형변환에 해당하고, 다운캐스팅은 명시적형변환에 해당합니다.



업캐스팅(upcasting)

그렇다면 업캐스팅은 과연 무엇일까요?

업캐스팅(upcasting)이란? 서브 클래스 객체를 슈퍼 클래스 타입으로 타입 변환하는 것

서브 클래스 객체를 슈퍼 클래스 타입으로 타입 변환을 한다는 것에서 우리는 업캐스팅과 다운캐스팅은 상속 관계에서만 이루어진다는 것을 유추할 수 있겠죠?

솔직히 이론으로는 잘 와닿지 않을 것입니다. 바로 예제를 볼까요?



부모클래스인 PersonPerson클래스를 상속받은 자식클래스인 Student클래스가 있습니다.

main에서 Person p가 생성이 되었죠? 이 때는 객체가 생성되지 않고 그저 p라는 이름의 껍데기만 만들어진 상태입니다.

바로 다음에 자식클래스인 Student s = new Student("이재문");의 형태로 객체가 생성이 되었습니다.
이 때, StudentPerson클래스를 상속받았기 때문에
위의 모든 멤버변수와 메서드를 바라보며 접근할 수 있습니다.


그 다음을 볼까요? 드디어 업캐스팅이 이루어졌습니다.

Person p;
Student s = new Student("이재문");
p = s;

위의 코드는 아래와 같습니다.

Person p;
Student s;
p = new Student("이재문");

s가 업캐스팅이 되었습니다. 우리는 이것을 sp로 부른다. 라고 칭하겠습니다.
자식클래스를 슈퍼클래스로 부른다. 라고도 말할 수 있겠군요.


자동차와 전기차가 그 예시입니다.
자동차를 부모클래스라고, 전기차를 자식클래스라고 칭해봅시다.

우리는 전기차를 볼 때 "전기차다!" 라고 할 수도 있지만 "자동차다!"라고 말할 수도 있습니다.
하지만 아무 자동차나 보고서 "전기차다!" 라고 말을 할 수는 없겠죠? 자동차 중에서는 전기차도 있지만 전기차가 아닌 차도 많으니까요.


따라서 p = s를 통해 우리는 전기차를 자동차라고 부를 수 있는 것입니다.

이렇게 전기차를 자동차로 업캐스팅시켰을 때, 볼 수 있는, 즉 접근할 수 있는 멤버변수와 메서드는 자동차인 Person클래스 안의 멤버와 메서드밖에 없습니다.
우리는 전기차가 아닌 자동차의 시선으로 바라보고 있기 때문에 Student클래스가 바라보는 것이 아닌 Person클래스가 바라보는 것만을 접근할 수 있는 것입니다.


밑의 컴파일 오류가 나는 부분을 볼까요?

p객체는 지금 s객체입니다. 하지만 Person타입으로 업캐스팅이 된 상태이므로 사실상 Person클래스가 접근할 수 있는 것들인 name id Person(String name)만 사용할 수 있습니다.

그래서 Person클래스 안에는 name멤버변수는 있지만 gradedepartmentp가 볼 수 없는 Student클래스에 있기 때문에 접근하지 못해 오류가 나는 것입니다.


업캐스팅(upcasting) 정리

  1. 업캐스팅은 자동형변환(형변환)에 해당한다.
  2. 업캐스팅과 다운캐스팅은 상속관계에서만 이루어질 수 있다.
  3. sPerson타입으로 업캐스팅시키면 s객체는 Person이 바라보는 것들만을 접근할 수 있다.


다운캐스팅(downcasting)

위의 업캐스팅을 이해했다면 다운캐스팅은 훨씬 쉽습니다.

슈퍼클래스 객체를 서브클래스 타입으로 변환하는 것

쉽게 말해 업캐스팅으로 인해 서브클래스 객체가 슈퍼클래스 타입이 된 것을 원래대로 되돌려 놓는다는 얘기입니다.
좁아진 시선을 다시 원래대로 넓힌다고 말할 수도 있겠네요.


앞에서 다운캐스팅은 명시적형변환이라고 말했던 기억이 나시나요?
명시적형변환을 할 때에는 타입 변환 표시를 꼭 해주어야 했듯, 다운캐스팅을 할 때에도 자식클래스의 타입을 반드시 명시해주어야 합니다.

class Person {..}
class Student extends Person {...}
...
Person p = new Student("이재문"); // 업캐스팅
...
Student s = (Student)p; // 다운캐스팅

더 정확한 이해를 위해 다운캐스팅 예시를 함께 봅시다.

위의 사진에서

Person p = new Student("이재문");

으로 업캐스팅이 되었죠? 그렇다면 pStudent객체지만 Person클래스가 볼 수 있는 name id Person()만 접근하여 사용할 수 있을 것입니다.


그 다음 새로운 Student객체인 s가 선언이 되고,
그 이후에 Student객체이며 Person타입인 p(Student)p로 인해 다시 Student타입으로 변환하는 다운캐스팅이 일어납니다.

이러한 다운캐스팅을 통해 다시 pStudent타입이 되며 grade department Student()도 함께 접근하여 사용할 수 있게 됩니다.


Student타입인 것과 Student객체인 것은 엄연히 구분되어야 합니다. "타입"과 "객체"에 주의하며 다시 정독해보세요!


다운캐스팅은 업캐스팅이 된 객체에만 가능하다.

주의할 점입니다! 다운캐스팅은 반드시 업캐스팅이 된 객체에만 가능합니다.

업캐스팅이 되지 않은 부모객체에 다운캐스팅을 시도하는 것은 생각해보면 당연히 안 되는 것입니다.
원래 상속관계에서는 부모클래스가 자식클래스에 접근할 수 없는데 부모클래스를 다운캐스팅하는 행위는 이가 가능하도록 만들어줄 수 있기 때문이죠.

단순히 업(UP)을 해주었으니 다시 다운(DOWN)을 해주는 것이라고 생각하면 더 이해가 쉬우실 겁니다.


💡( 참고 ) 업캐스팅이 되지 않은 객체에 다운캐스팅을 시도하면 각각의 실행과 컴파일이 될까요??
정답은 컴파일은 되지만 실행은 되지 않습니다.

  • 컴파일 성공 : 컴파일러는 껍데기만 봅니다. 앞뒤 가리지 않고 그저 부모클래스니까 다운캐스팅이 가능하므로 통과를 시켜줍니다.
  • 실행 실패 : 하지만 실행을 할 경우에는 이 부모클래스가 업캐스팅이 되었는지 안 되었는지를 파악할 수 있기 때문에 실행을 실패하게 됩니다.

그럼 다시 예제 사진으로 넘어가서 오류가 나는지 안 나는지를 볼까요?

s.name을 출력하면 이재문이라는 이름이 잘 출력이 될 것입니다.
이것은 p를 다운캐스팅하지 않아도 접근이 가능했던 부분입니다.

s.grade = "A";부분 또한 오류가 나지 않습니다.
이는 p를 다운캐스팅한 것을 s에 저장하여 Student타입이 되었기 때문에 grade에 접근이 가능해진 덕분입니다.


다운캐스팅(downcasting) 정리

  1. 다운캐스팅은 명시적형변환에 해당하여 형변환하는 자식클래스의 타입을 명시해주어야 한다.
  2. "타입"인 것과 "객체"인 것은 다르다. 부모클래스 타입인데 자식클래스 객체이면 업캐스팅이 된 것이라고 한다.
  3. 다운캐스팅은 업캐스팅이 된 객체에만 가능하다. 이는 실행때 오류가 나게 된다.

업캐스팅과 다운캐스팅을 이해하는 데에 도움이 되었길 바랍니다!!



profile
개발새발 블로그

0개의 댓글