형변환(참조형)

성혜·2024년 1월 22일
0

Java

목록 보기
10/25
post-thumbnail

형변환, Type Casting

참조형 형변환

  • 상속 관련
  • 상속 관계에 있는 클래스끼리만 형변환이 가능하다.
  • 직계 > 가능
  • 방계 > 불가능

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

  • Vector는 객체를 잠깐 담을 수 있는 저장소
    ( java.util.Vector클래스를 import)

  • Object obj = name; //스트링형의 객체를 Object형의 객체로 업캐스팅
  • Object obj = id; //Integer형의 객체를 Object형의 객체로 업캐스팅

그래서 아래와 같이 표현 가능

Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);

백터에서 객체를 얻고 바로 다운 캐스팅하면 아래와 같은 구문도 가능
String str2 = (String)v.elementAt(0);
Integer num2 = (Integer)v.elementAt(1);
profile
하루를 정리하고 기록합니다.

0개의 댓글