캐스팅(Casting)?
캐스팅이란 타입을 변환하는 것을 말하며 형변환
이라고도 한다. 자바의 상속 관계에 있는 부모와 자식 클래스 간에 간의 형변환이 가능하다.
업캐스팅(Upcasting)
업캐스팅이란 자식 클래스의 객체가 부모 클래스 타입으로 형변환 되는 것
을 말한다.
Parent
l
Child
Parent형의 객체를 생성하고자 할 때 Child형의 정보를 좌변에 제공하는 것이다.
Parent p = new Child();
즉 업캐스팅
이란, 하위 클래스의 정보를 담을수 있는 객체에 상위클래스의 자료형을 부여해서, 상위클래스처럼 사용하게 하는 것이다.
아래 코드에서 부모 클래스는 Parent, 자식 클래스는 Child이다. Parent p = c; 부분이 업캐스팅한 부분이다. p가 Child 객체를 가리키지만, p는 Parent 타입이기 때문에 Parent 클래스의 멤버에만 접근이 가능하다. 그렇기 때문에 p.check에서 컴파일 에러가 발생한다.
class Parent{
String name;
Parent(String name){
this.name = name;
}
}
class Child extends Parent{
String check;
Student(String name){
super(name);
}
}
public class Main{
public static void main(String[] args){
Child s = new Child("홍길동");
Parent p = c; // 업캐스팅
p.name = "이름";
p.check = "컴파일 에러 발생"; // 컴파일 에러 발생
}
}
다운캐스팅(Downcasting)
업캐스팅 된 것을 다시 원상태로 돌리는 것을 말한다. 그러면 단순히 업캐스팅의 반대
라고 생각하면 될까?
그건 아니다.
다운캐스팅이란 하위클래스(Child)의 정보를 담을 수 있는 객체의 자료형이 상위 클래스(Parent)로 전환되어 있던 것(업캐스팅된 객체)을 다시 되돌리는 것을 의미한다. 업캐스팅 되었던 객체의 자료형을 다시 하위클래스의 정보를 담는 기능을 하도록 자료형을 Child로 바꾸어서 되돌려 놓는 것을 말한다.
Parent p = new Child(); //업캐스팅 -p는 Parent형.
Child c = (Child) p; //다운캐스팅! -p는 Child형.
원칙적으로 다운캐스팅 혼자만 쓰면 우변이 좌변에서 필요한 정보를 모두 채워주지 못하기 때문에 불가능한 문장이 되므로, 꼭 업캐스팅이 선행되어야 한다는 것을 명심히야 한다.
아래 코드를 보면 Child c = (Child)P; 라 나오는 부분이 다운캐스팅이다.
class Parent{
String name;
Parent(String name){
this.name = name;
}
}
class Child extends Parent{
String check;
Child(String name){
super(name);
}
}
public class Main{
public static void main(String[] args){
Parent p = new Child("홍길동");
Child c = (Child)p; // 다운캐스팅
s.name = "이순신";
s.check = "check!";
}
}
업캐스팅과 다운캐스팅을 쓰는 이유!!
객체 지향의 특징 중 하나인 다형성과 관련 있다.
상속 받은 클래스가 몇 개 든 상관없이 하나의 인스턴스로 묶어서 관리하기 위함이다.
앞에서 예시로 쓴 Parent 와 Child보다 이해하기 쉬운 예시가 있어서 다른 예시로 들어보겠다.
과자'라는 부모 클래스가 있고, 이 클래스를 상속받아서 '죠리퐁', '새우깡', '오감자' 같은 자식 클래스를 만들었다고 생각해보자.
부모 클래스에는 '뜯다'라는 메소드가 있다고 생각하자.
그럼 죠리퐁을 먹든, 새우깡을 먹든, 오감자를 먹든, 일단 '뜯다'는 동일할 것이다.
과자가 무엇이든간에 상관없이.
그럴 때 이 상속과 업캐스팅이 유용하게 쓰이는 것이다.
만약 업캐스팅 없이 상속받은 자식 클래스를 통해서 메서드를 호출한다고 생각하면,
if (타입이 죠리퐁이면)
죠리퐁.뜯다();
else if (타입이 새우깡이면)
새우깡.뜯다();
else if (타입이 오감자이면)
오감자.뜯다();
이렇게 될 것이다.
하지만 부모 클래스에 업캐스팅을 하게 되면,
class 과자먹는꼬마()
{
public void 과자먹기(과자 g)
{
g.뜯다();
// 이후엔 먹겠죠:D
}
}
이렇게 해서 과자먹는꼬마 클래스의 과자먹기 메소드를 호출할 때는
그 과자가 죠리퐁이든 새우깡이든 오감자든 그냥 넘겨만 주면
부모 클래스인 과자 타입으로 업캐스팅이 되어서 꼬마는 아무생각없이 뜯어먹을 수 있다...는 것이다.
물론 이런 경우, 자식 클래스에만 선언된 메소드를 사용하려면 자식 클래스 타입으로 캐스팅을 해야 한다. 하지만 어떤 메소드에서 자식 클래스에 기본으로 선언된 기능들을 이용해서 진행할 경우에는, 어떻게 바뀔 지 모를 모든 자식 클래스에 대한 코드를 생성하기 보다는 부모 클래스에 대해서 코드를 생성하는 쪽이 더 나을 것이다.
[출처][https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ttaeseung&logNo=120045432495] https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=ttaeseung&logNo=120045432495
'Java' 카테고리의 다른 글
[자바] super와 super() (0) | 2022.10.02 |
---|---|
[자바] 오버라이드(Override) (0) | 2022.10.01 |
[자바] ArrayList 란? (0) | 2022.09.29 |
[자바] 접근 제어자 (0) | 2022.09.28 |
[자바] BufferReader 와 BufferWriter (0) | 2022.09.27 |