[ios/swift]Type Casting

감자맨·2022년 8월 1일
0

swift

목록 보기
12/14
post-thumbnail

📒📕 📗📘📙📚📖 swift 문법을 공부하자!📒📕 📗📘📙📚📖

업캐스팅/다운캐스팅

표현식이 변환할 Type과 호환된다면, 변환할 Type으로 캐스팅된 인스턴스를 리턴한다. 상속 관계인 업캐스팅과 다운 캐스팅에서 사용한다.

업캐스팅

class Cafe {
    let menu: String
    init(menu: String) {
        self.menu = menu
    }
}
class Latte: Cafe { }
class Tea: Cafen { }
 
 
let order: [Cafe] = [
    Latte.init(menu: "green tea latte"),
    Tea.init(menu: "EarlGray"),
    Tea.init(menu: "peppermint")
]

Latte와 Tea라는 타입의 인스턴스가 들어갈 수 있는 이유는 업캐스팅을 했기에 가능. Latte와 Tea란 클래스는 서로 다른 타입의 클래스 이지만 부모 클래스(Cafe)가 같다. 둘의 슈퍼 클래스가 Cafe으로 동일하기 때문에, 이 둘을 Cafe란 클래스로 업캐스팅 해서 묶어버린 것.

class Cafe {
    let name: String = "Starbucks"
}
class Latte: Cafe {
    let menu: String = "green tea latte"
}
class Shot: Cafe {
    let shots: Int = 1
}
let cafe = Latte.init() as Cafe

👉 Latte 타입의 인스턴스를 생성하지만, 이를 Cafe 타입으로 업캐스팅해서 cafe에 저장하겠다.
Latte란 인스턴스가 온전히 메모리에 올라감. cafe가 Latte란 서브 클래스를, Cafe란 슈퍼클래스 타입으로 참조하는 업캐스팅을 한 것이기 때문에, cafe의 접근 범위가 'Cafe' 멤버로 한정된다.

cafe.name             // Starbucks
cafe.menu         // Value of type 'Cafe' has no member 'menu'

이렇게, Cafe 클래스의 멤버인 name엔 접근할 수 있지만,
서브 클래스 Latte의 멤버인 menu엔 접근할 수 없다. 서브 클래스의 인스턴스를 슈퍼 클래스의 타입으로 참조하는 것을 업캐스팅이라고 함

다운캐스팅

슈퍼 클래스 인스턴스를 서브 클래스의 타입으로 참조한다. 업캐스팅된 인스턴스를 다시 원래 서브 클래스 타입으로 참조할 때 사용한다.
as?와 as!연산자를 이용해 어떤 타입의 인스턴스인지 확인할 수 있다.
as?는 특정 타입이 맞는지 확신할 수 없을때 사용하고, as!는 특정 타입이라는 것이 확실한 경우에 사용한다. 단 as!으로 다운캐스팅을 했는데 지정한 타입이 아니라면 런타임 에러가 발생한다.

Cafe 타입으로 업캐스팅된 cafe 변수를 다시 하위 클래스인 Latte 타입으로 변환해서 넣어 줌.

var latte: Latte = cafe as! Latte
latte.menu        // green tea latte

Any, AnyObject 타입 캐스팅

  • Any : 모든 타입을 저장한다.
  • AnyObject : 모든 클래스 타입을 저장한다
    Any 타입엔 Value 타입(구조체, 열거형), Reference 타입(클래스, 클로저) 상관 없이 저장이 가능하다.
var things: [Any] = []
 
things.append(1)
things.append(3.5)
things.append("coffee")
things.append(false)        
things.append(Cafe.init()))        
things.append({ print("Tasty!") })  

as를 이용한 패턴 매칭.

for thing in things {
    switch thing {
    case _ as Int:
        print("Int Type!")
    case _ as Double:
        print("Double Type!")
    case _ as String:
        print("String Type!")
    case _ as Cafe:
        print("Cafe Type")
    case _ as () -> ():
        print("Closure Type")
    default:
        print("something else")
    }
}

as? as!를 이용한 다운캐스팅

if var name = name as? String {
    name.append("Good!")
}
profile
나는 코딩하는 감자다!

0개의 댓글