• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    해결됨

클래스 형식 변환에서 is 연산자 질문드립니다

21.01.06 14:56 작성 조회수 127

0

공부를 하다가 예문에서

class Mammal{}

class Dog : Mammal{}

class Cat : Mammal{} 세 개의 클래스를 만들고

Main에서

Mammal mammal = New Dog();

Dog dog;

if(mammal is Dog)

{ dog = (Dog)mammal;}

라는 코드를 봤습니다

여기서 if문 조건이 참이라고 하는데, mammal 이 어째서 Dog 타입인건가요?? mammal 은 Dog 인스턴스를 가리키긴 하지만 Mammal 타입 아닌가요?? 저는 거꾸로 Dog 인스턴스가 Mammal 타입으로(부모클래스로) 형식변환된다고 이해하고 있었습니다.

또한 if문 조건이 참이라고 한다면, mammal 이 Dog 타입이라는 사실이 밝혀졌는데 if문 안에서 (Dog)mammal; 이라는게 필요한건가요??

답변 4

·

답변을 작성해보세요.

2

Cat, Dog 모두 포유류이기 때문에,
Mammal mammel이라는 변수로
Mammal 타입은 물론 Cat, Dog 모두 참조할 수 있습니다.

이렇게 부모 타입으로 관리하면
Cat, Dog 할 것 없이 둘의 공통 분모인
Mammel이라는 공통 클래스의 기능들을 활용할 수 있게 됩니다.
다만 Cat, Dog만 특수하게 들고있는 변수나 함수는 사용할 수 없습니다. (ex. Mew, Bark 등)

그러나 mammel 변수로 관리한다고 해서
근본적으로 그 포유류의 태생이 소실된 것은 아닙니다.
언제든지 그 포유류의 원본 타입을 확인해서
다시 Dog / Cat 변수를 이용해 참조하게 바꿀 수가 있습니다.

if (mammal is Dog)의 의미는
[이 포유류는 개가 맞습니까]? 라는 질문을 던진 것과 같습니다.

mammal이라는 변수는 어떠한 포유류도 다 담을 수 있는데,
그것이 Cat일 수도, Dog일 수도 있습니다.
따라서 Dog dog = mammel;만 해주면 에러를 뱉는데
모든 포유류가 다 Dog라는 보장은 없으니,
문법적으로 말이 안 된다 간주하고 통과시켜주지 않습니다.
따라서 정말 우리가 개라는 확신이 있으면 (Dog)를 붙여
강제로 캐스팅을 해줘야 합니다.

개라는 확신을 갖기 위해 is 문법은 사용할 수가 있는데,
실제로 만들어진 객체 (new Dog을 했는지, new Cat을 했는지)의 런타임 정보를 이용해 확인하게 됩니다.
여기서 ~is Dog는 말 그대로 원본 객체가 Dog이 맞는지 확인하는 것이지
딱히 뭔가를 변환해주거나 하는 부분이 포함되어 실행되진 않습니다.
따라서 실제로 Dog 참조 타입으로 사용하고 싶으면
위와 마찬가지로 (Dog)mammal로 캐스팅이 필요합니다.

if (mammel is Dog) // 개가 맞긴 맞냐?
   dog = (Dog) mammel; // ㅇㅋ 그럼 개로 다시 변신~

참고로 [확인] + [캐스팅]을 동시에 하는 as 문법도 있는데

dog = mammel as Dog;  // 개가 맞으면 변신, 아니면 null

로 작성할 경우
mammel이 Dog이 아니라면 null로 채워지고,
그게 아니라면 정상적으로 캐스팅이 됩니다.

1

[mammal은 Dog 객체를 참조하고 있기 때문에 mammal is Dog이 참이 될 수 있는 건가요??]
-> 네 이게 100% 맞습니다.

그리고 무조건 실제 객체를 이용한 판단이기 때문에,
Mammal m = new Mammal()을 했다면 그냥 표유류를 만든거지
딱히 Dog/Cat을 만든게 아니기 때문에
m is Dog / m is Cat 모두 false가 리턴됩니다.
마찬가지로 m = new Cat()을 한 다음
m is Dog를 해도 (고양이는 개가 아니기 때문에) false가 리턴됩니다.

이 부분은 OOP에서 특히나 중요하기 때문에 이런 저런 테스트로 실습을 해보시기 바랍니다.

0

ZIOMIN님의 프로필

ZIOMIN

질문자

2021.01.06

책을 봐도 명확히 설명이 안되어있어서 헷갈렸는데 정말 감사합니다!!!

0

ZIOMIN님의 프로필

ZIOMIN

질문자

2021.01.06

감사합니다! 그렇다면 여기서 mammal은 Dog 객체를 참조하고 있기 때문에 mammal is Dog이 참이 될 수 있는 건가요??

아니면 근본적으로 상위클래스인 Mammal타입은 Dog타입, Cat타입으로 체크를 할 수 있는건가요??

그러니까

Mammal mammal = new Dog(); 을 하지 않고 순수하게 Mammal mammal = new Mammal(); 을 한 상태라고 해도

mammal is Dog 이나 mammal is Cat true 값을 리턴하나요??