본문 바로가기

IOS

swift - 타입캐스팅 by yagom

728x90
반응형

스트프트의 타입캐스팅은 인스턴스의 타입을 확인하는 용도

또는 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할 수 있는지 확인하는 용도로 사용한다.

is, as를 사용한다.

 

/*
let someInt: Int = 100
let someDouble: Double = Double(someInt) # C언어 및 다른 대부분의 언어에서 사용하는 방법
// 이 방법은 스위프트에서는 타입캐스팅이 아닌 Double타입의 인스턴스를 하나 더 생성하는 것이다.
*/



// 타입 캐스팅을 위한 클래스 정의
// 상속을 활용한 부모와 자식 클래스 

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

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

class UniversityStudent: Studnet {
	var majot: String = ""
    func goToMT(){
    	print("멤버쉽 트레이닝을 갑니다. 신남!")
    }
}

var yagom: Person = Person() # 사람 클래스 인스턴스 생성
var hana: Studnet = Student() # 학생 클래스 인스턴스 생성
var jason: UniversityStudent = UniversityStudnet() # 대학생 클래스 인스턴스 생성
// is 를 사용하여 타입을 확인한다.

var result: Bool # Boolean 타입

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 yagom is UniversityStudent{
	print("yagom은 대학생입니다.")
} else if yagom is Studnet {
	print("yagom은 학생입니다.")
} else if yagom is Person{
	print("yagom은 사람입니다.")
} // yagom은 사람입니다.

switch jason{
case is Person:
	print("jason은 사람입니다.") # break에 걸리게된다.
case is Studnet:
	print("jason은 학생입니다.")
case is UniversityStudent:
	print("jason은 대학생입니다.")
default:
	print("jason은 사람도, 학생도, 대학생도 아닙니다.")
} // jason은 사람입니다.

switch jason{
case is UniversityStudent:
	print("jason은 대학생입니다..") # break에 걸리게된다.
case is Studnet:
	print("jason은 학생입니다.") 
case is Person:
	print("jason은 사람입니다..")
default:
	print("jason은 사람도, 학생도, 대학생도 아닙니다.")
} // jason은 대학생입니다.

업캐스팅 (많이 사용하지는 않음)

as를 사용하여 부모클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 타입정보를 전환해준다.

Any 혹은 AnyObject로도 타입정보를 변환할 수 있다.

암시적으로 처리되므로 생략해도 무방하다.

var mike: Person = UniversityStudent() as Person // UniversityStudent는 Person을 상속받은 관계이므로 가능
var jenny: Studnet = Student()
//var jina: UniversityStudent = Person() as UniversityStudent // 컴파일 오류
var jina: Any = Person() // as Any 생략가능

다운캐스팅

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

 

조번부 다운 캐스팅 as?

조건부 다운 캐스팅은 optional로 반환된다.

var optionalCasted: Student?

optionalCasted = mike as? UniversityStudent // Person타입으로 지정되어있어도 실질적으로 UniversityStudent의 성질을 가지므로 캐스팅 가능
optionalCasted = jenny as? UniversityStudent // nil
optionalCasted = jina as? UniversityStudent // nil
optionalCasted = jina as? UniversityStudent // nil

강제 다운 캐스팅 as!

반환 타입이 일반 타입이므로 좀 더 편하게 활용된다.

var forcedCasted: Student

optionalCasted = mike as! UniversityStudent // Person타입으로 지정되어있어도 실질적으로 UniversityStudent의 성질을 가지므로 캐스팅 가능
optionalCasted = jenny as! UniversityStudent // 런타임 오류
optionalCasted = jina as! UniversityStudent // 런타임 오류
optionalCasted = jina as! UniversityStudent // 런타임 오류

 

활용 방식

func doSomeThingWithSwith(someone: Person){
	switch someoneP{
    case is UniversityStudent:
    	(someone as! UniversityStudent).goToMT()
    case is Student:
    	(someone as! Student).goToSchool()
    case is Person
    	(someone as! Person).breath()
    }
}
// 주로 함수로 전달되는 경우 해당 인스턴스가 해당되는 클래스를 확인 할 수 있다.


// 캐스팅과 동시에 언래핑해서 옵셔널 결과값을 받아와서 사용하기도 한다.
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 as mike) // 멤버쉽 트레인닝을 갑니다 신남!
doSomething(someone: mike as jenny) // 등교를 합니다.
doSomething(someone: mike as yagom) // 숨을 쉽니다.

 

반응형