Swift 타입 캐스팅(2020.10.30)

  • 스위프트의 타입 케스팅은 인스턴스의 타입을 확인하는 용도
  • 또는 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할수 있는지 확인하는 용도로 사용한다.
  • is, as 를 사용한다
// 다은 언어에서 타입케스팅은 다음과 같다.

// 아래 코드는 정확히 말하자면 타입캐스팅이 아니다.
// Int 타입을 받아서 더블타입의 메모리생성하고 할당해서 인스턴스를 만든다.
let someInt : Int = 100
let someDouble: Double = Double(someInt)

// Any 타입 혹은 AnyObject타입을 많이 사용하게 된다면 타입케스팅이 매우 중요해진다.
// 타입 캐스팅을 위한 클래스 정의
class Person{
    var name: String = ""
    func breath(){
    	print("숨을 쉽니다")
    }
}

class Student:Person{
    var school : String = ""
    func breath(){
    	print("숨을 쉽니다")
    }
}

class Student:Person{
	var school: String = ""
    func goToSchool(){
    	print("등교를 합니다.")
    }
}

class UniversityStudent : Student {
	var major : String = ""
    func goToMT(){
    	print("멤버쉽 트래이팅을 갑니다. 싄남!")
    }
}

var yaogom:Person = Person()
var hana : Student = Student()
var jason : UniversityStudent = UniversityStudent()

타입 확인

// is를 사용하여 타입을 확인합니다.

var result : Bool

 result = yagom is Person // true
 result = yagom is Student // false
 result = yagom is UniversityStudent // false
 
 result = hana is Person // true
 result = hana is Student // true
 result = hana is UniversityStudent // false
 
 result = jason is Person // true
 result = jason is Student // true
 result = jason is UniversityStudent // true
 
//  if - else 구문
 if yagom is UniversityStudent {
 	print("yagom은 대학생 입니다.")
 } else if yagom is Student{
 	print("yagom은 학생입니다.")
 } else if yagom is Person {
 	print("yagom은 사람입니다.")
 } //yagom은 사람입니다.
 
// switch 구문
switch jason{
	case is Person:
		print("jason은 사람입니다.")
	case is Student:
    		print("jason은 학생입니다.")
    case is University:
    	print("jason은 대학생입니다.")
    default:
    	print("jason은 사람도, 학생도, 대학생도 아닙니다.")
} // jason은 사람입니다.

-------------------------------------------------------
switch jason{
	case is University:
    	print("jason은 대학생입니다.")
    case is Student:
    	print("jason은 학생입니다.")
    case is Person:
    	print("jason은 사람입니다.")
    default:
    	print("jason은 사람도, 학생도, 대학생도 아닙니다.")
} // jason은 대학생입니다.


-------------------------------------------------------
switch hana{
	case is University:
    	print("hana는 대학생입니다.")
    case is Student:
    	print("hana는 학생입니다.")
    case is Person:
    	print("hana는 사람입니다.")
    default:
    	print("hana는 사람도, 학생도, 대학생도 아닙니다.")
} // hana는 대학생입니다

업 캐스팅

  • as 를 사용하여 부모클래스의 인스턴스로 사용할수 있도록 컴파일러에게 타입 정보를 알려준다.
  • Any 혹은 AnyObject 로도 타입정보를 변환할수 있다.
  • 암시적으로 실행되므로 생략해도 된다.
  • 많이 사용하지는 않는다.
var mike : Person = UniversityStudent () as Person
var jenny : Student = Student()
// var jina : UniversityStudent= Person() as UniversityStudent // 컴파일 오류 
var jina : Any = Person()  // as Any 생략 가능

다운 캐스팅

  • as?(조건부 다운 캐스팅) 또는 as!(강제 다운캐스팅) 를 사용하여
  • 자식 클래스의 인스턴스로 사용할수 있도록
  • 컴파일러에게 인스턴스의 타입 정보를 전환해준다.

조건부 다운 캐스팅

// as?
// 조건부 다운 캐스팅을 하면 nil 값이 나올수 있으므로 옵셔널을 반환한다.

	var OptionalCasted : Student?
    
    OptionalCasted = mike as? UniversityStudent
    OptionalCasted = jenny as? UniversityStudent // nil
    OptionalCasted = jina as? UniversityStudent // nil
    OptionalCasted = jina as? Student //nil

강제 다운 캐스팅

// 반환 타입이 옵셔널 타입이 아닌 일반 타입이기 때문에 활용측면에서 편리하다

	var forcedCasted : Student?
    
    forcedCasted = mike as! UniversityStudent
    // forcedCasted = jenny as! UniversityStudent // runtime error
    // forcedCasted = jina as! UniversityStudent // runtime error
    // forcedCasted = jina as! Student // runtime error

활용

	func doSomethingWithSwitch(someone:Person){
    	switch someone:
        	case is University: // 인스턴스 인지만 확인한다. 사용하려면 아래처럼 캐스팅을 해서 활용해야하는 경우가 발생한다.
            	(someone as! UniversityStudent).goToMT()
            case is Student:
            	(someone as! Student).goToSchool()
            case is Person:
            	(some as! Person).breath()
    }


doSomethingWithSwitch(someone: mike as Person)
// 멤버쉽 트래이팅을 갑니다. 싄남!
doSomethingWithSwitch(someone: mike)
// 멤버쉽 트래이팅을 갑니다. 싄남!
doSomethingWithSwitch(someone: jenny)
// 등교합니다.
doSomethingWithSwitch(someone: yagom)
// 숨을 쉽니다.


-------------------------------------------------------
// if let 을 사용하면 캐스팅과 동시에 언래핑 된 인스턴스를 반환 받아서 사용할 수 있다.
func doSomething(someone: Person){
	if let universityStudent = someone as? UniversityStudent{
    	universityStudent.goToMT()
    } else if let student = someone as? Student{
    	student.goToSchool()
    } else if let person = someONe as? Person{
    	person.breath()
    }
}

doSomething(someone : mike as Person)
// 멤버쉽 트래이팅을 갑니다. 싄남!

doSomething(someone : mike)
// 멤버쉽 트래이팅을 갑니다. 싄남!

doSomething(someone : jenny)
// 등교합니다.

doSomething(someone : yagom)
// 숨을 쉽니다.

출처 : 유튜브 "yagom"

좋은 웹페이지 즐겨찾기