참조형 형변환
- 상속 관련
- 상속 관계에 있는 클래스끼리만 형변환이 가능하다.
- 직계 > 가능
- 방계 > 불가능
1. 업캐스팅, Up Casting
: 암시적인 형변환
: 자식 클래스 > (형변환) > 부모클래스로
: 100% 안전
2. 다운캐스팅, Down Casting
: 명시적인 형변환
: 부모 클래스 > (형변환) > 자식 클래스
: 100% 안전x
class Shape {
public void draw(){
System.out.println("모양을 그립니다");
}
public void delete(){
System.out.println("모양을 지웁니다");
}
}
class Circle extends Shape {
public void draw(){
System.out.println("원을 그립니다");
}
public void delete(){
System.out.println("원모양을 지웁니다");
}
public void sayCircle(){
System.out.println("안녕하세요 원입니다");
}
}
class Triangle extends Shape {
public void draw(){
System.out.println("삼각형을 하나, 둘, 셋, 그립니다.");
}
public void delete(){
System.out.println("삼각형을 지웁니다");
}
public void sayTriangle(){
System.out.println("안녕하세요 삼각형입니다");
}
}
class Rectangle extends Shape {
public void draw(){
System.out.println("사각형을 원, 투, 쓰리, 포 그립니다.");
}
public void delete(){
System.out.println("사각형을 지웁니다");
}
public void sayRect(){
System.out.println("안녕하세요 사각형입니다");
}
}
//abstract을 테스트하기 위한 클래스
public class UpcastingClassTest{
public static void main(String[] args){
Shape s = new Shape();
s.draw();
s.delete();
System.out.println();
//클래스의 기본적인 사용법
Circle c = new Circle();
c.draw();
c.delete();
c.sayCircle();
System.out.println();
Triangle t = new Triangle();
t.draw();
t.delete();
t.sayTriangle();
System.out.println();
Rectangle r = new Rectangle();
r.draw();
r.delete();
r.sayRect();
System.out.println();
//Upcasting의 사용
Shape c1 = new Circle();
c1.draw();
c1.delete();
//c1.sayCircle(); 에러가 발생합니다.
System.out.println();
Shape t1 = new Triangle();
t1.draw();
t1.delete();
//t1.sayTriangle(); 에러가 발생합니다.
System.out.println();
Shape r1 = new Rectangle();
r1.draw();
r1.delete();
//r1.sayRect(); 에러가 발생합니다.
}
}
//결과
모양을 그립니다
모양을 지웁니다
원을 그립니다
원모양을 지웁니다
안녕하세요 원입니다
삼각형을 하나, 둘, 셋, 그립니다.
삼각형을 지웁니다
안녕하세요 삼각형입니다
사각형을 원, 투, 쓰리, 포 그립니다.
사각형을 지웁니다
안녕하세요 사각형입니다
원을 그립니다
원모양을 지웁니다
삼각형을 하나, 둘, 셋, 그립니다.
삼각형을 지웁니다
사각형을 원, 투, 쓰리, 포 그립니다.
사각형을 지웁니다
원래 객체를 생성 할 때 보통은 아래와 같이 합니다.
Circle c = new Circle();
하지만 upcasting을 이용하면 아래와 같이 표현해 객체를 생성 할 수 있습니다.
Shape c1 = new Circle();
이때,
c1은 재정의된 메서드를 호출 했을 때 누구의 메서드를 호출할까요?
c1은 Shape형이기 때문에 Shape 내의 멤버 메서드를 호출 하는 것이 맞습니다. 즉, draw와 delete를 사용할 수 있습니다.
만일 재정의된 draw와 delete가 있다면 Circle의 draw와 delete를 사용합니다.
=> 이를 upcasting이라고 부릅니다.
❗주의 할 점❗
소스코드의 에러부분
c1.sayCircle(); 에러가 발생합니다.
에러가 나는 이유는 재정의된 메서드가 아니기 때문입니다. Shape에 sayCircle()이라는 메서드가 없기 때문에 아들을 찾아갈 수 없습니다.
c1은 Shape형입니다!! upcasting으로 인해 형 그자체를 까먹으면 안됩니당!
: upcating 한 것을 다시 복구시켜주는 작업
: 정확한 형으로 다운캐스팅 하지 않으면 무조건 에러!!
import java.util.Vector;
public class UpDownCasting{
public static void main(String[] args){
String name = new String("홍길동");
Integer id = new Integer(1000);
Vector v = new Vector();
v.addElement(name);
v.addElement(id);
Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
String str = (String)obj1;
Integer num = (Integer)obj2;
System.out.println("이름:" + str+ " 번호:" + num);
String str2 = (String)v.elementAt(0);
Integer num2 = (Integer)v.elementAt(1);
System.out.println("이름:" + str2+ " 번호:" + num2);
}
}
//결과
이름:홍길동 번호:1000
이름:홍길동 번호:1000
그래서 아래와 같이 표현 가능
Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
String str2 = (String)v.elementAt(0);
Integer num2 = (Integer)v.elementAt(1);