반응형
Greensky0026
삽질러의 대환장 공사판
Greensky0026
전체 방문자
오늘
어제
  • 분류 전체보기 (241)
    • Language (56)
      • JAVA (13)
      • Swift (38)
      • Kotlin (4)
      • Dart (0)
      • PHP (0)
      • JavaScript (1)
    • IDE & Framework (92)
      • Spring (10)
      • Android (48)
      • iOS (8)
      • NodeJS (1)
      • CodeIgniter (3)
      • Flutter (1)
      • 분류중 (18)
    • Infra (8)
    • Database (12)
    • VCS (4)
    • Debug Log (34)
      • java (7)
      • swift (3)
      • Android (9)
      • Web (7)
      • 삽질기 (7)
    • Others (19)
      • 코딩테스트 풀이 (0)
      • IT 이야기 (18)
    • 쉼터 (2)
    • 개발공부 (14)
      • Network (1)
      • 자료구조와 알고리즘 (2)
      • Code design (8)
      • ETC (1)
      • 아카이브 (1)

블로그 메뉴

    공지사항

    • 프로그래머스 코딩 테스트 관련글 비공개 처리

    인기 글

    태그

    • Java
    • JSP
    • 프로그래밍
    • 코딩테스트
    • 구축
    • map
    • 타입
    • kotlin
    • reduce
    • Android
    • 개발
    • 예제
    • xcode
    • IT
    • level1
    • 공부
    • ios
    • swift
    • swfit
    • 프로그래머스

    최근 댓글

    최근 글

    티스토리

    hELLO · Designed By 정상우.
    Greensky0026

    삽질러의 대환장 공사판

    Swift 타입캐스팅 (형변환)
    Language/Swift

    Swift 타입캐스팅 (형변환)

    2021. 3. 13. 12:52
    반응형

     Swift의 타입캐스팅은 인스턴스의 타입을 확인거나

    클래스의 인스턴스를 부모 또는 자식클래스의 타입으로 사용할 수있는지

    확인하는 용도로 사용합니다. is 또는 as를 사용합니다.

     

    그림으로 간단히 설명해보겠습니다.

    Person - Study - Programming 순으로 부모-자식클래스라고 생각해봅시다.

     

     Programming 클래스는 Psrson클래스의 자식 클래스인 Study의 자식클래스입니다.

    Person을 상속한 Study를 상속했으니, 당연히 Person의 모든 프로퍼티가 있습니다. 따라서 true입니다

     반대로 Person은 Programming의 모든 프로퍼티를 갖고 있지 않아서

    Person클래스는 Programming으로 사용이 불가능합니다.

     

     반대로 Person은 Programming의 모든 프로퍼티를 갖고 있지 않아서

    Person클래스는 Programming으로 사용이 불가능합니다.

     

    예제를 위한 클래스 정의

    class Person{
    	var name: String = ""
    	static func breath(){ print("가만히 있습니다.") }
    }
    
    class Study: Person{
    	var study: String = ""
    	static func study(){ print("공부를 합니다.") }
    }
    
    class Programming: Study{
    	var programming: String = ""
    	static func programming() { print("컴퓨터로 공부를 합니다") }
    }
    
    
    var greensky: Person = Person()
    var lee : Study = Study()
    var kim: Programming = Programming()

     

    is를 통한 타입 확인

    var result: Bool
    result = greensky is Person //true
    result = greensky is Study //false
    result = greensky is Programming //false
    
    result = lee is Person //true
    result = lee is Study //true
    result = lee is Programming //false
    
    result = kim is Person //true
    result = kim is Study //true
    result = kim is Programming //true
    
    if lee is Study {
    	Programmin.programming()
    } else if lee is Study{
    	Study.study()
    } else if lee is Programming{
    	Person.breath()
    }
     // 공부를 합니다.
    
    case is Person : 
    	Programming.programming()
    case is Study :
    	Study.study()
    case is Programming :
    	Person.breath()
    default : 
    	print("뭐하고 있는지 모르겠습니다.")
    }
     //컴퓨터로 공부를 합니다

     

    *소소한 주의점

    더보기

    조건의 순서도 굉장히 중요합니다!! 아래처럼 사용하시면 의미가 없습니다.

    func typeCheck(name: Any){
    	switch name{
    		case is Person : 
    			Person.breath()
    		case is Study :
    			Study.study()
    		case is Programming :
    			Programming.programming()
    		default : 
    			print("뭐하고 있는지 모르겠습니다.")
    	}   
    }
    
    typeCheck(name: greensky) // 가만히 있습니다.
    typeCheck(name: lee) // 가만히 있습니다.
    typeCheck(name: kim) // 가만히 있습니다.

     

     

    업 캐스팅

     

    as를 사용해 부모클래스의 인스턴스로 사용할 수 있도록

    컴파일러에게 타입정보를 전환해줍니다.

    Any / AnyObject로도 타입정보를 변환할 수 있는데, 암시적으로 처리되므로

    꼭 필요하지 않다면 생략해도 됩니다.

    인스턴스를 세개 추가해 보겠습니다.

    //bob은 Programming 인스턴스를 생성해 Person클래스 타입으로 쓰도록 업캐스팅
    var bob: Person = Programming() as Person
    var mike: Study = Study()
    //Any로 업캐스팅하는 경우 as Any를 생략할 수 있습니다.
    var jina: Any = Person() //as Any 생략

     

    자, 여기서 bob과 kim은 모두 Programming클래스의 인스턴스입니다.

    하지만 bob은 Person클래스 타입으로 업캐스팅을 했죠. 차이를 볼까요?

    func typePersnon(name: Study){
    	return print("수행되었습니다.")
    }
    
    typePersnon(name: bob) //error
    typePersnon(name: kim) //수행되었습니다

     

    서로 같은 Programming클래스를 참조하지만 bob은 업캐스팅이 되어서

    typePersnon의 매개변수로 bob은 사용할 수 없습니다!

     

     

    다운 캐스팅

    자식클래스의 인스턴스로 사용할 수 있도록 컴파일러에게

    인스턴스 타입정보를 전환해줍니다.

     

    조건부 다운 캐스팅

    as?를 사용해 캐스팅합니다.

    //실패시 nil을 반환하므로 결과타입은 옵셔널입니다.
    var optionalCasted: Study?
    optionalCasted = bob as? Programming //Optional(SwiftPlayground.Programming)
    optionalCasted = mike as? Programming //nil
    optionalCasted = mike as? Programming //nil
    optionalCasted = jina as? Programming //nil

    bob은 Progamming클래스이지만 Person으로 타입캐스팅을 했었죠?

    하지만 Progamming클래스의 프로퍼티를 모두 갖고 있으므로

    다운캐스팅에 성공한 모습입니다.

     

    강제 다운 캐스팅

    as!를 사용해 캐스팅합니다. 실패시 오류가 발생하며, 성공시 일반타입을 반환합니다.

    var forcedCasted: Study
    optionalCasted = bob as! Programming //SwiftPlayground.Programming
    optionalCasted = mike as! Programming //error
    optionalCasted = mike as! Programming //error
    optionalCasted = jina as! Programming //error

     

    활용

    class Person{
    	var name: String = ""
    	func breath(){ print("가만히 있습니다.") }
    }
    
    class Study: Person{
    	var study: String = ""
    	func studing(){ print("공부를 합니다.") }
    }
    
    class Programming: Study{
    	var programming: String = ""
    	func computing() { print("컴퓨터로 공부를 합니다") }
    }
    class Dog{
        var name: String = ""
        func bark() { print ("왈왈") }
    }
    
    var yoon: Person = Person()
    var jina: Study = Study()
    var nakamura: Programming = Programming()
    var happy: Dog = Dog()
    
    func doSomeThing(someone: Any){
        switch someone {
        case is Programming:
            (someone as! Programming).computing()
        case is Study:
            (someone as! Study).studing()
        case is Person:
            (someone as! Person).breath()
        default:
            print("사람이 아닌데용")
        }
    }
    doSomeThing(someone: yoon) //가만히 있습니다.
    doSomeThing(someone: jina) //공부를 합니다.
    doSomeThing(someone: jina as Person) //공부를 합니다.
    doSomeThing(someone: nakamura) //컴퓨터로 공부를 합니다
    doSomeThing(someone: happy) //사람이 아닌데용
    
    
    func doSomeThingOptional(someone: Any){
        if let progamming = someone as? Programming{
            progamming.computing()
        } else if let study = someone as? Study{
            study.studing()
        } else if let person = someone as? Person{
            person.breath()
        } else {
            print("사람이 아닌데용")
        }
    }
    doSomeThingOptional(someone: yoon) //가만히 있습니다.
    doSomeThingOptional(someone: jina) //공부를 합니다.
    doSomeThingOptional(someone: jina as Person) //공부를 합니다.
    doSomeThingOptional(someone: nakamura) //컴퓨터로 공부를 합니다
    doSomeThingOptional(someone: happy) //사람이 아닌데용

     

     

     


    공부에 도움을 준 사이트

     

    전체적인 공부 가이드라인

    http://www.yagom.net 

     

    야곰닷넷 - yagom.net

    iOS 개발자들의 놀이터, 배움터, 모임터, 기록보관소 야곰닷넷입니다.

    yagom.net

     

    스위프트 공식 가이드 번역 사이트 : 타입캐스팅

    jusung.gitbook.io/the-swift-language-guide/language-guide/18-type-casting

     

    타입캐스팅 (Type Casting)

     

    jusung.gitbook.io

     

    반응형

    'Language > Swift' 카테고리의 다른 글

    Swift 프로토콜 기초  (0) 2021.03.14
    Swift Assert와 Guard  (0) 2021.03.14
    Swift 인스턴스의 생성과 소멸  (0) 2021.03.12
    Swift 프로퍼티 타입들  (0) 2021.03.12
    Swift 클로저  (0) 2021.03.11
      'Language/Swift' 카테고리의 다른 글
      • Swift 프로토콜 기초
      • Swift Assert와 Guard
      • Swift 인스턴스의 생성과 소멸
      • Swift 프로퍼티 타입들
      Greensky0026
      Greensky0026
      점이 모여 선이 된다. 내 삽질도 언젠간 거대한 지하 도시가 되겠지!

      티스토리툴바