Type Casting ??? 타입 캐스팅이 뭔가요

조회수 4927회

타입캐스팅을 어떻게 상상해야 할까요???

머릿속에서 그 타입캐스팅이 이루어지는 과정을 상상하고 싶어요.

(타입캐스팅이 성공한다는 가정하에...) 메모리 상에서는 그 Object의 크기가 변하는건 아닌것 같은데, (다시 타입 캐스팅이 되니까.)

  • (•́ ✖ •̀)
    알 수 없는 사용자

2 답변

  • 자바에서 타입 캐스팅은 2가지 경우가 있는데요.

    우선 기본형 타입은 작은 데이터 타입에서 큰 데이터 타입에 값을 담을때는 별도 작업이 필요 없지만 반대의 경우에는 명시적으로 타입캐스팅을 해 주어야 합니다. 아래 코드를 참고하세요.

    class CodeRunner{
        public static void main(String[] args){
            int intNum = 1000;
            //큰 그릇인 long에 작은 그릇인 int의 값을 담을때는 type casting을 명시하지 않아도 된다.
            long longNum = intNum;
    
            //여기서는 아래와 같이 명시적으로 int로 타입캐스팅하지 않으면
            //possible lossy conversion from long to int 에러가 발생
            intNum = (int)longNum;
        }
    }
    

    타입캐스팅 과정에서 원래 값의 메모리가 변경되는게 아니라, 그 값이 복사되서 새로운 메모리에 저장되는겁니다.

    자세한 내용은 기본형 타입 변환 강의를 참고하세요.


    Object의 type casting은 상속 받은 경우에도 가능한데요. 예를들어 아래 코드와 같이 type casting을 할 수도 있습니다.

    class CodeRunner{
        public static void main(String[] args){
            //Animal을 상속 받은 Human은 Animal로 type casting 할 수 있음
            Human humanObject1 = new Human();
            Animal animalObject1 = humanObject1;
    
            // 하지만 반대로 Human이 Animal로 type casting 될 수는 없음
            // 왜냐하면 Human은 Animal의 모든 기능을 포함하므로 
            // "Human은 Animal이다"라고 할 수 있지만
            // "Animal"은 "Human이다"라고 할 수는 없으므로
            // 아래 코드는 에러 발생
            Animal animalObject2 = new Animal();
            Human humanObject2 = animalObject2;
        }
    }
    
    class Animal{
        int age;
    }
    
    class Human extends Animal{
        String name;    
    }
    

    Object의 type casting에서는 메모리상에서 그 내용이 복사되지는 않습니다. 다만 animalObject1이 Human인스턴스의 기능중, Animal에 해당하는 기능만 사용할 수 있게되는겁니다.

    자세한 내용은 클래스 형변환 강의를 참고하세요.

    • 답변 감사드립니다! )) Animal에 해당하는 기능만 사용할 수 있게되는겁니다. ==> 이건 Java 컴파일러를 만든 사람이 정한건가요? 알 수 없는 사용자 2016.8.6 21:33
    • 그러니까 , 아마도 , 컴파일러를 만드는 사람 입장에서는 , 제 코드가 하나의 명령이고 , animalObject1이 원래는 Human인스턴스든 아니든 상관없이 , Animal class type이기 때문에 당연히 그 이외의 펑션에는 접근을 못하도록 설정을 해 놨어야 하는게 마땅한거겠죠?? (너무 당연한건가요..) 알 수 없는 사용자 2016.8.6 21:34
    • 제가 animalObject1은 Animal class type이다! 라고 명명 했고 , 실제로 animalObject1이 가지고 있는 여러 타입중(2개) 하나가 Animal이 있었기 때문에 , 실행시에 아무 문제가 없었던 것이고, 강제로 animalObjec2 를 Human class type으로 형 변환을 했을 때는 , 그런 타입이 animalObject2에는 없어서 실패하는 것이겠지요? 알 수 없는 사용자 2016.8.6 21:49
    • 네. 설명하신 내용이 맞습니다. 정토드 2016.8.7 05:51
    • 감사합니다~. 알 수 없는 사용자 2016.8.7 12:45
  • 타입 캐스팅에 대해 기본적인 것은 안다고 가정하고 제가 아는 부분에 대해서 설명해드리겠습니다. 타입 캐스팅의 과정을 글로 설명하는 것 보다는 코드와 함께보면 더 이해가 쉬울 것 같네요.

    메인 메서드부터 따라 가시면 됩니다.

    public class 도형 {
        public void draw(){}
    
        public static void doSomthing(도형 shape){
    
            shape.draw();
    
            /*
            서브 클래스 원(circle), 삼각형(circle) 타입의 파라미터를 
            슈퍼 클래스인 도형(shape)으로 업 캐스팅하여 받았기에 컴파일 오류가 없습니다.
    
            서브 클래스는 슈퍼 클래스와 크기가 같거나 큽니다.
            서브 클래스는 슈퍼 클래스를 상속받아 작성하였기에, 슈퍼 클래스에 존재하는 것들은 기본적으로 서브 클래스에 존재하기에
            형변환을 생략해도 상관없고, 컴파일 오류가 나지 않습니다.
    
            해당 메서드가 실행되는 시점(런타임)에 서브 클래스의 특정 메서드를 실행할지 결정합니다.(동적바인딩)
            이후에 요청받은 받은 서브 클래스의 메서드를 실행하게 됩니다.
             */
        }
    
        public static void main(String[] args) {
            원 circle = new 원();
            삼각형 triangle = new 삼각형();
    
            doSomthing(circle); // 실행결과 : 원을 그리다
            doSomthing(triangle); // 실행결과 : 삼각형을 그리다
    
            /*
            서브 클래스 원(circle), 삼각형(triangle) 의 타입으로 파라미터를 전달합니다.
            doSomething 메서드에서는 전달 받은 파라미터를 슈퍼 클래스인 도형(shape)으로 업 캐스팅을 합니다.
             */
        }
    }
    
    class 원 extends 도형 {
        @Override
        public void draw() {
            System.out.println("원을 그리다");
        }
    }
    
    class 삼각형 extends 도형 {
        @Override
        public void draw() {
            System.out.println("삼각형을 그리다");
        }
    }
    

    객체지향 프로그래밍 기본원리는 객체지향 프로그래밍에 대해 제가 간단하게 정리한 내용인데 도움이 되었으면 좋겠네요.

    • 답변 감사드립니다~ 동적 바인딩이 뭔지 더 찾아봐야 되겠네요! 덕분에 모르는것 하나 더 알아 갑니다. 알 수 없는 사용자 2016.8.6 21:55

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)