[다양한 표현 및 확장] 12. 타입 캐스팅

Seoyoung Lee·2022년 2월 24일
0


2021년 12월 29일에 공부한 내용입니다.

1. 스위프트 타입 캐스팅

  • 인스턴스의 타입을 확인하는 용도
  • 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할 수 있는지 확인하는 용도
  • is, as를 사용함
  • let someDouble: Double = Double(someInt)와 같은 형변환은 타입 캐스팅이 아니라 Double 타입의 인스턴스를 새로 생성한 것이다.
// 타입 캐스팅을 위한 클래스 정의
class Person {
    var name: String = ""
    func breath() {
        print("숨을 쉽니다")
    }
}

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

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

// 인스턴스 생성
var seoyoung: Person = Person()
var beomgyu: Student = Student()
var soobin: UniversityStudent = UniversityStudent()

2. 타입 확인

is를 사용하여 타입을 확인한다.

var result: Bool

result = seoyoung is Person // true
result = seoyoung is Student // false
result = seoyoung is UniversityStudent // false

result = beomgyu is Person // true
result = beomgyu is Student // true
result = beomgyu is UniversityStudent // false

result = soobin is Person // true
result = soobin is Student // true
result = soobin is UniversityStudent // true

if seoyoung is UniversityStudent {
    print("seoyoung은 대학생입니다")
} else if seoyoung is Student {
    print("seoyoung은 학생입니다")
} else if seoyoung is Person {
    print("seoyoung은 사람입니다")
} // seoyoung은 사람입니다

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

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

3. 업 캐스팅(Up Casting)

  • as를 사용하여 부모 클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 타입정보를 전환해준다.
  • Any 혹은 AnyObject로도 타입정보를 변환할 수 있다.
  • 암시적으로 처리되므로 꼭 필요한 경우가 아니라면 생략해도 무방하다.
// UniversityStudent 인스턴스를 생성하여 Person 행세를 할 수 있도록 업 캐스팅
var mike: Person = UniversityStudent() as Person

var jenny: Student = Student()
// var jina: UniversituStudent = Person() as UniversityStudent // 컴파일 오류

// UniversityStudent 인스턴스를 생성하여 Any 행세를 할 수 있도록 업 캐스팅
var jina: Any = Person() // as Any 생략가능

4. 다운 캐스팅(Down Casting)

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

A. 조건부 다운 캐스팅

  • as? 사용
  • 캐스팅에 실패하면, 즉 캐스팅하려는 타입에 부합하지 않는 인스턴스라면 nil을 반환하기 때문에 결과의 타입은 옵셔널 타입이다.
var optionalCasted: Student?

optionalCasted = mike as? UniversityStudent // 실질적으로 할당된 인스턴스가 대학생이기 때문에 Person이어도 UniversityStudent로 캐스팅 가능
optionalCasted = jenny as? UniversityStudent // nil
optionalCasted = jina as? UniversityStudent // nil
optionalCasted = jina as? Student // nil

B. 강제 다운 캐스팅

  • as! 사용
  • 캐스팅에 실패하면, 즉 캐스팅하려는 타입에 부합하지 않는 인스턴스라면 런타임 오류가 발생한다.
  • 캐스팅에 성공하면 옵셔널이 아닌 일반 타입을 반환한다.
var forcedCasted: Student

forcedCasted = mike as! UniversityStudent
// forcedCasted = jenny as! UniversityStudent // 런타임 오류
//forcedCasted = jina as! UniversityStudent // 런타임 오류
//forcedCasted = jina as! Student // 런타임 오류

5. 활용

func doSomethingWithSwitch(someone: Person) {
    switch someone {
        case is UniversituStydent:
        (someone as! UniversituStudent).goToMT()
        case is Student:
        (someone as! Student).goToSchool()
        case is Person:
        (someone 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) // 숨을 쉽니다
profile
나의 내일은 파래 🐳

0개의 댓글