ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unity]유니티 입문하기 6-10(클래스의 형변환)
    프로그래밍 2023. 8. 17. 20:20

    이전 글에서는 클래스의 상속에 대해 배우며 Human의 하위 클래스인 Adult와 Baby를 만들어보았습니다.

    이번 글에서는 클래스의 상속으로 인해 일어날 수 있는 형변환에 대하여 알아보겠습니다.


    앞선 글에서 변수의 형변환에 대하여 배울 때, 형변환에는 암시적 형변환과 명시적 형변환이 있다고 배웠습니다.

    암시적 형변환은 좁은 범위에서 넓은 범위의 자료형으로 형변환이 일어나는 것이었고,

    명시적 형변환은 넓은 범위에서 좁은 범위의 자료형으로 형변환이 일어날 때 이를 직접 명시해 형변환해 주는 방식이었습니다.

     

    클래스의 경우에도 이를 적용할 수 있는데요, 객체를 인스턴스화 할 때 잘 보면 결국 우리가 정의한 클래스라는 형태의 자료형의 변수에 객체를 저장하는 것임을 알 수 있습니다.

    즉, 클래스는 자료형처럼 동작한다는 것인데요, 이를 통해 클래스 간의 형변환이 어떻게 이루어질지 예상해 볼 수 있습니다.

     

    암시적 형변환

    물론, 모든 클래스가 서로간에 형변환이 가능하지는 않습니다.

    하지만 상속으로 묶인 클래스의 경우에는 자식 클래스가 부모 클래스의 하위 클래스이기 때문에, 자식 클래스를 부모 클래스로 형변환 할 때에는 암시적 형변환이 가능합니다.

    Adult maria = new Adult("John", 10, 12);
    Human human = maria;

    이는 부모 클래스가 자식 클래스들을 모두 포함하는, 더 넓은 범위의 클래스이기 때문에 가능한 것입니다.

     

    명시적 형변환

    그렇다면 다른 자료형들처럼 명시적 형변환을 한다면 반대로 부모 클래스를 자식 클래스로의 형변환이 가능할까요?

    Human robert = new Human("robert", 32, 172);
    Adult adult = (Adult)robert;

    언뜻 보기에는 아무 문제도 없어보이는 코드이지만, 실제 프로젝트에서 위의 코드를 입력하고 실행해 보면, 놀랍게도 아래와 같은 에러가 발생합니다.

    사실 이런 오류가 발생하는 이유는 간단합니다. 위와 같이 부모타입의 객체를 부모타입의 변수에 담아 저장한 경우, 세분화되어 자식 클래스에만 있는 멤버나 메서드를 표현할 수 없기 때문이죠.

     

    이를 반대로 말할 경우 자식타입의 객체를 부모 클래스 변수에 담아뒀다가, 다시 자식 클래스로 옮기는 경우에는 명시적 형변환이 가능하다는 말이기도 합니다.

     

    Human jason = new Adult("jason", 32, 172);
    Adult adult = (Adult)jason;

    위와 같이, 암시적 형변환을 통해 Human 클래스(부모 클래스)의 변수에 Adult 클래스(자식 클래스)의 객체를 암시적 형변환으로 저장한 뒤, 이를 명시적 형변환을 통해 Adult 클래스의 변수에 담는다면 명시적 형변환이 가능해집니다.

     

    as 연산자, is 연산자

    위와 같이, 명시적 형변환을 실행할 경우에는 값형 변수의 형변환보다 비교적 까다로운 조건이 필요함을 알았습니다.

    하지만 복잡한 코드 속에서 그것을 일일히 다 확인할 수는 없겠죠.

    이때 사용할 수 있는 것이 as 연산자is 연산자 입니다.

     

    as 연산자

    as연산자는 명시적 형변환에 이용한 캐스팅 연산자와 같이 형변환을 실행하는 연산자인데요,

    연산자 왼쪽에 온 변수가 연산자 오른쪽에 온 타입으로 형변환이 가능하다면 형변환을 실행하고, 불가능하다면 빈 값인 null을 반환하는 특징이 있습니다.

     

    Human Paul = new Human("Paul", 32, 172);
    Baby baby = Paul as Baby;
    
    if(baby == null)
    {
        Debug.Log("형변환 실패");
    }
    else
    {
        Debug.Log("형변환 성공");
    }

    그래서 만약 위와 같이 코드를 작성한 뒤 실행해 보면 앞서 발생한 오류가 발생하지 않는 것을 알 수 있습니다.

    물론, 명시적 형변환이 불가능한 경우이므로 형변환에 실패했다는 로그를 확인할 수 있을 겁니다.

     

    반대로 위 코드에서 new Human 부분을 new Baby로 고쳐서 명시적 형변환이 가능하게 만들면, 이렇게 형변환에 성공했다는 메시지를 받을 수 있습니다.

     

    as 연산자는 클래스와 같은 참조형 변수에만 사용할 수 있으며, 정수형, 실수형 등 값형 변수에 사용할 경우 에러를 반환하니 잘 알아둡시다.

     

    is 연산자

    그렇다면 is 연산자는 무슨 역할을 하는 것일까요?

    is 연산자의 경우, as 연산자와 같이 실제로 형변환을 수행하지는 않습니다.

    하지만, as 연산자와 같이 캐스팅이 가능한지 확인한 뒤에, 캐스팅이 가능하다면 true를, 아니라면 false를 반환하는 연산자로, 순수하게 형변환이 가능한지 여부를 확인하는 역할만 수행합니다. 또한, is 연산자는 as 연산자와 달리 값형 변수(정수형, 실수형 등)에도 사용할 수 있습니다.

     

    Human Alexis = new Adult("Alexis", 32, 172);
    Debug.Log(Alexis is Adult);

    is 연산자 사용 예시와 결과

     

Designed by Tistory.