차근차근 개발중

[swift] 타입 캐스팅(Type Casting) 본문

개발/Swift

[swift] 타입 캐스팅(Type Casting)

zaenny 2023. 10. 8. 20:57

📍 타입 캐스팅(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타입의 값을 강제 언래핑한 타입
      • 실패시 런타임 오류
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