차근차근 개발중
[swift] 타입 캐스팅(Type Casting) 본문
📍 타입 캐스팅(Type Casting)이란?
- 인스턴스의 "타입"을 확인하거나, 해당 인스터스를 슈퍼 클래스나 하위 클래스로 취급하는 방법입니다
- 인스턴스 타입을 검사 -is 연산자 / 클래스 계층 상의 타입 변환 - as 연산자
1) 최상위 클래스 MediaItem
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
2) MediaItem클래스를 상속받는 Movie와 Song클래스 생성
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
3) Movie와 Song 인스턴스를 담는 library 배열을 생성
let library = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
Movie(name: "Citizen Kane", director: "Orson Welles"),
Song(name: "The One And Only", artist: "Chesney Hawkes"),
Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
📍 is 연산자
표현식 is Type
- 타입에 대한 검사를 수행하는 연산자 , 런타임 시점에 체크가 이루어진다.
- 표현식이 타입과 동일하거나, 표현식이 타입의 서브 클래스인 경우 참이면 true 리턴 / 거짓이면 false 리턴
var movieCount = 0
var songCount = 0
for item in library {
if item is Movie {
movieCount += 1
} else if item is Song {
songCount += 1
}
}
print("Media library contains \(movieCount) movies and \(songCount) songs")
- 결과값
Media library contains 2 movies and 3 songs
📍as 연산자
표현 as type
표현 as? type
표현 as! type
- 인스턴스의 타입의 힌트를 변경하는 연산자
- 표현식이 변환할 타입과 호환된다면, 변환할 타입으로 캐스팅된 인스턴스를 리턴한다.
- 상속 관계인 업캐스팅과 다운 캐스팅에서 사용한다
- Any / AnyObject 타입을 사용할 경우, 상속 관계가 아니어도 예외적으로 사용할 수 있다.
📍업캐스팅과 다운캐스팅(Upcasting / Downcasting)
(1) Upcasting (업캐스팅)
- 인스턴스 as 타입
- 하위클래스의 메모리구조로 저장된 인스턴스를 상위클래스 타입으로 인식한다_ 항상 성공
- as 사용 또는 직접 타입을 명시해서 사용해도 된다
- 상호 호환가능한 타입도 항상 성공한다
let str: String = "Hello"
let otherStr = str as NSString
(2) Downcasting (다운캐스팅) (실패가능성이 있음)
- 슈퍼클래스 인스턴스를 서브 클래스의 타입으로 참조한다
- 인스턴스 as? 타입 / 인스턴스 as! 타입
- as? 연산자
- 참이면 반환타입은 Optional타입
- 실패시 nil 반환
- as! 연산자
- 참이면 반환타입은 Optional타입의 값을 강제 언래핑한 타입
- 실패시 런타임 오류
- as? 연산자
for item in library {
if let movie = item as? Movie {
print("Movie: \(movie.name), dir. \(movie.director)")
} else if let song = item as? Song {
print("Song: \(song.name), by \(song.artist)")
}
}
📍타입캐스팅의 의미
- 인스턴스 사용시에 어떤 타입으로 사용할지(속성/메서드) 메모리구조에 대한 힌트를 변경하는 것
- 메모리의 값을 수정하는 것이 아니다
- 단순히 해당 타입의 인스턴스인 것처럼 취급하려는 목적이다
📍상속과 다형성
다형성(Polymorphism)
- 하나의 객체(인스턴스)가 여러가지의 타입의 형태로 표현될 수 있음을 의미 또는 하나의 타입으로 여러 종류의 객체를 여러가지 형태(모습)로 해석될 수 있는 성격이다.
- 다형성이 구현되는 것은 "클래스의 상속"과 깊은 연관성이 있다.
상속을 통한 메서드의 재정의와 다형성
- "재정의된" 메서드(Undergraduate의 메서드 테이블)가 호출되어 실행
- 타입의 저장 형태는 속성/메서드에 대한 접근가능 범위를 나타내는 것이다
- 다형성은 인스턴스에서 메모리의 실제 구현 내용에 대한 것
- (메서드는 재정의 가능하고, 메서드 테이블을 통해 동작)
📍Any / AnyObject 타입
1)Any 타입
- 기본타입(Int, String, Bool)등 커스텀 클래스, 구도체, 열거형, 함수타입까지 포함해서 모든 타입의 인스턴스도 표현할 수 있는 타입 (옵셔널타입도 포함)
- 저장된 타입의 메모리 구조를 알 수없기 때문에, 항상 타입캐스팅해서 사용해야한다.
2)AnyObject타입
- 모든 클래스 타입의 인스턴스를 나타낼 수 있는 타입
3) 옵셔널값의 Any 변환
- 의도적인 옵셔널값의 사용
- Any는 모든 타입을 포함하므로, 의도적인 옵셔널값을 사용하려면 Any타입으로 변환하면 컴파일러가 알려주는 경고를 없앨 수 있음
Any와 AnyObject는 런타임 시점에 타입이 결정 된다. 필요한 경우에만 사용하며 이보다 특정 타입을 명시하는 것이 더 좋다고 한다.
'개발 > Swift' 카테고리의 다른 글
[Swift] 클래스와 구조체 (0) | 2023.09.17 |
---|
Comments