
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' 세 개의 클래스를 정의하였고, 각각의 인스턴스를 생성하였습니다.
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' 문을 사용하여 타입에 따른 출력을 할 수 있습니다.
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' 타입으로 취급하여 배열에 저장할 수 있습니다.
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'을 반환합니다.
var forcedCasted: Student
optionalCasted = mike as! UniversityStudent // 성공: mike는 UniversityStudent로 강제 다운 캐스팅
// optionalCasted = jenny as! UniversityStudent // 런타임 오류 발생
// optionalCasted = jina as! UniversityStudent // 런타임 오류 발생
// optionalCasted = jina as! Student // 런타임 오류 발생
강제 다운 캐스팅은 성공하면 해당 타입으로 변환되지만, 실패할 경우 런타임 오류가 발생합니다. 따라서 사용 시 주의가 필요합니다. 일반적으로 'as!'는 타입이 확실한 경우에만 사용하고, 안전성을 위해 'as?'를 선호합니다.
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) // 숨을 쉽니다.
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' 구문을 사용하여 타입 캐스팅을 활용한 예제입니다. 각각의 타입에 따라 다른 메서드를 호출합니다.