[Swift] 12. 타입캐스팅

Hoojeong Kim·2022년 3월 9일
0

Swift Base

목록 보기
14/22
post-thumbnail

타입캐스팅

타입캐스팅은 인스턴스의 타입을 확인하거나 자신을 다른 타입의 인스턴스인양 행세할 수 있는 방법으로 사용할 수 있다. 타입캐스팅은 isas 연산자로 구현할 수 있다.

is 연산자 : 값의 타입을 확인
as 연산자 : 다른 타입으로 전환

그렇다면, 지금부터 타입캐스팅을 통해 데이터 타입을 확인하거나 다른 타입으로 전환해보자.


타입캐스팅의 동작을 확인하기 위해서 다음 클래스를 선언한다.
import UIKit

class MediaItem {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Movie: MediaItem {
    var director: String
    init(name: String, director: String) {
        self.director = director
        super.init(name: name)
    }
}

class Music: MediaItem {
    var artist: String
    init(name: String, artist: String) {
        self.artist = artist
        super.init(name: name)
    }
}

let library = [
    Movie(name: "기생충", director: "봉준호"),
    Music(name: "Butter", artist: "BTS"),
    Movie(name: "올드보이", director: "박찬욱"),
    Music(name: "Savage", artist: "aespa"),
    Music(name: "INVU", artist: "태연")
]

데이터 타입 확인

타입 확인 연산자인 is 를 사용하여 인스턴스가 어떤 클래스의 인스턴스인지 타입을 확인할 수 있다. is 연산자는 인스턴스가 해당 클래스 또는 그 자식클래스의 인스턴스라면 true를 반환하고, 그렇지 않다면 false를 반환한다.

이때 예시를 클래스 인스턴스로 든 것이지, is 연산자는 모든 데이터 타입에 사용할 수 있다.


다음 코드는 library 배열의 요소에 모두 접근하여, is 연산자를 사용해 해당 요소가 Media의 자식클래스인 Movie인지, Music인지 판별하는 코드이다.
var movieCount = 0
var musicCount = 0

for item in library {
    if item is Movie {
        movieCount += 1
    } else if item is Music {
        musicCount += 1
    }
}

print("Media library contains \(movieCount) movies and \(musicCount) musics")
Media library contains 2 movies and 3 musics

library 배열을 보면, 타입 확인이 정상적으로 이루어져 정확한 경과가 출력된 것을 알 수 있다.

다운캐스팅

다운캐스팅은 as 연산자를 사용하여 부모클래스 타입의 인스턴스를 자식클래스 타입으로 다운하여 캐스팅하는 것을 말한다.

특정 클래스 타입의 상수나 변수는 하위 클래스의 인스턴스를 참조할 수 있는데, 예를 들면 MediaItem 타입으로 선언된 library 배열인스턴스를 다운캐스팅하여 MediaItem의 자식클래스인 Movie, Music 타입으로 캐스팅하여 참조할 수 있다.


이때 다운캐스팅을 실패할 수 있기 때문에, as연산자는 두 가지 형식으로 제공된다.

as? : 조건부 연산자로, 실패시 nil을 반환
as! : 다운캐스팅을 강제하며, 실패시 런타임 에러

다운캐스팅에 실패할 가능성이 조금이라도 있다면 as? 연산자를 사용하는 것이 좋다.


그렇다면, 다음 코드를 보자.
for item in library {
    if let movie = item as? Movie{
        print("Movie: \(movie.name), dir. \(movie.director)")
    } else if let music = item as? Music {
        print("Music: \(music.name), by \(music.artist)")
    }
}
Movie: 기생충, dir. 봉준호
Music: Butter, by BTS
Movie: 올드보이, dir. 박찬욱
Music: Savage, by aespa
Music: INVU, by 태연
profile
나 애기 개발자 👶🏻

0개의 댓글