[Swift] 타입 캐스팅 (Type Casting)

김형근·2024년 7월 22일

[Swift] 문법

목록 보기
15/20
post-thumbnail

🍎 [Swift] 타입 캐스팅 (Type Casting)

  • Swift에서 타입 캐스팅은 인스턴스의 타입을 확인하거나, 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할 수 있는지를 확인하는 데 사용됩니다. 'is''as' 키워드를 사용하여 타입 캐스팅을 수행할 수 있습니다.

🍏 타입 캐스팅을 위한 클래스 정의

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 geuni: Person = Person() // Person 타입 인스턴스
var hana: Student = Student() // Student 타입 인스턴스
var jason: UniversityStudent = UniversityStudent() // UniversityStudent 타입 인스턴스

'Person', 'Student', 'UniversityStudent' 세 개의 클래스를 정의하였고, 각각의 인스턴스를 생성하였습니다.


🍏 타입 확인

  • 'type 확인' 을 통해 인스턴스의 타입을 확인할 수 있습니다. 'is' 키워드를 사용하여 인스턴스가 특정 타입인지 확인합니다.
var result: Bool

result = geuni is Person // true, geuni는 Person 타입입니다.
result = geuni is Student // false, geuni는 Student 타입이 아닙니다.
result = geuni is UniversityStudent // false, geuni는 UniversityStudent 타입이 아닙니다.

result = hana is Person // true, hana는 Person 타입입니다.
result = hana is Student // true, hana는 Student 타입입니다.
result = hana is UniversityStudent // false, hana는 UniversityStudent 타입이 아닙니다.

result = jason is Person // true, jason은 Person 타입입니다.
result = jason is Student // true, jason은 Student 타입입니다.
result = jason is UniversityStudent // true, jason은 UniversityStudent 타입입니다.

'is' 키워드를 사용하여 인스턴스가 특정 타입인지 확인할 수 있습니다. 이 예제에서는 각 인스턴스가 'Person', 'Student', 'UniversityStudent' 타입인지 확인하였습니다.


🧃 타입 확인 결과에 따른 출력

  • 타입 확인 결과에 따라 조건문을 사용하여 다른 출력을 할 수 있습니다.
if geuni is UniversityStudent {
    print("geuni는 대학생입니다.")
} else if geuni is Student {
    print("geuni는 학생입니다.")
} else if geuni is Person {
    print("geuni는 사람입니다.")
} // 출력: geuni는 사람입니다.

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

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

'if' 문과 'switch' 문을 사용하여 타입에 따른 출력을 할 수 있습니다.


🍏 업 캐스팅 (Upcasting)

  • '업 캐스팅' 은 자식 클래스의 인스턴스를 부모 클래스 타입으로 사용하는 것을 의미합니다. 'as' 키워드를 사용합니다.
var mike: Person = UniversityStudent() as Person // UniversityStudent를 Person으로 업 캐스팅
var jenny: Student = Student() // Student 타입 인스턴스
// var jina: UniversityStudent = Person() as UniversityStudent // 컴파일 오류 발생
var jina: Any = Person() // 'as Any' 생략 가능

업 캐스팅은 자식 클래스의 인스턴스를 부모 클래스 타입으로 변환하는 것입니다. 이 예제에서는 'UniversityStudent' 타입의 인스턴스를 'Person' 타입으로 업 캐스팅하였습니다.

업 캐스팅은 일반적으로 자식 클래스 인스턴스를 부모 클래스 타입으로 취급할 때 사용합니다.
예를 들어, 다양한 클래스의 인스턴스를 동일한 부모 클래스 타입의 배열에 저장할 때 유용합니다.

let people: [Person] = [geuni, hana, jason, mike]

모든 인스턴스를 'Person' 타입으로 취급하여 배열에 저장할 수 있습니다.


🍏 다운 캐스팅 (Downcasting)

  • '다운 캐스팅' 은 부모 클래스의 인스턴스를 자식 클래스 타입으로 사용하는 것을 의미합니다. 'as?' 또는 'as!' 키워드를 사용합니다.

🧃 조건부 다운 캐스팅

  • 'as?' 키워드를 사용하여 조건부로 다운 캐스팅을할 수 있습니다. 성공하면 옵셔널 타입으로 반환됩니다.
var optionalCasted: Student?

optionalCasted = mike as? UniversityStudent // 성공: mike는 UniversityStudent로 다운 캐스팅
optionalCasted = jenny as? UniversityStudent // nil: jenny는 UniversityStudent가 아님
optionalCasted = jina as? UniversityStudent // nil: jina는 UniversityStudent가 아님
optionalCasted = jina as? Student // nil: jina는 Student가 아님

조건부 다운 캐스팅은 성공할 경우 옵셔널 타입으로 반환되며, 실패할 경우 'nil'을 반환합니다.

🧃 강제 다운 캐스팅

  • 'as!' 키워드를 사용하여 강제로 다운 캐스팅할 수 있습니다. 실패할 경우 런타임 오류가 발생합니다.
var forcedCasted: Student

optionalCasted = mike as! UniversityStudent // 성공: mike는 UniversityStudent로 강제 다운 캐스팅
// optionalCasted = jenny as! UniversityStudent // 런타임 오류 발생
// optionalCasted = jina as! UniversityStudent // 런타임 오류 발생
// optionalCasted = jina as! Student // 런타임 오류 발생

강제 다운 캐스팅은 성공하면 해당 타입으로 변환되지만, 실패할 경우 런타임 오류가 발생합니다. 따라서 사용 시 주의가 필요합니다. 일반적으로 'as!'는 타입이 확실한 경우에만 사용하고, 안전성을 위해 'as?'를 선호합니다.


🍏 활용 예제

  • 타입 캐스팅을 활용하여 인스턴스의 타입에 따라 다른 메서드를 호출할 수 있습니다.

🧃 switch 문을 사용하는 예제

func doSomethingWithSwitch(someone: Person) {
    switch someone {
    case is UniversityStudent:
        (someone as! UniversityStudent).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: geuni) // 숨을 쉽니다.

🧃 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: geuni) // 숨을 쉽니다.

'switch' 문과 'if-let' 구문을 사용하여 타입 캐스팅을 활용한 예제입니다. 각각의 타입에 따라 다른 메서드를 호출합니다.

profile
꾸준히 기록하기

0개의 댓글