타입 캐스팅 (Type Casting)
is 연산자 (type check operator)
- 타입에 대한 검사 수행
- true or false 리턴
- 이항연산자 형태
class Person {
var id = 0
var name = "이름"
var email = "abc@gmail.com"
}
class Student: Person {
var studentId = 1
}
class Undergraduate: Student {
var major = "전공"
}
let person1 = Person()
let student1 = Student()
let undergraduate1 = Undergraduate()
person1 is Person
person1 is Student
person1 is Undergraduate
student1 is Person
student1 is Student
student1 is Undergraduate
undergraduate1 is Person
undergraduate1 is Student
undergraduate1 is Undergraduate
as 연산자 (type cast operator)
다운캐스팅
- as! : Optional 타입을 강제 언래핑한 타입 리턴
업캐스팅
let person: Person = Undergraduate()
person.id
person.name
person.email
let ppp = person as? Undergraduate
if let ppp = person as? Undergraduate {
ppp.id
ppp.name
ppp.email
ppp.studentId
ppp.major
}
let ppp = person as! Undergraduate
let undergraduate2: Undergraduate = Undergraduate()
let person4 = undergraduate2 as Person
person4.id
person4.name
상속과 다형성(Polymorphism)
- 다형성 : 하나의 인스턴스(객체)가 여러가지 타입의 형태로 표현될 수 있다.
- 다형성의 구현은 클래스의 상속과 밀접한 관련이 있다.
class Person {
var id = 0
var name = "이름"
var email = "abc@gmail.com"
func walk() {
print("사람이 걷는다.")
}
}
class Student: Person {
var studentId = 1
override func walk() {
print("학생이 걷는다.")
}
func study() {
print("학생이 공부한다.")
}
}
class Undergraduate: Student {
var major = "전공"
override func walk() {
print("대학생이 걷는다.")
}
override func study() {
print("대학생이 공부한다.")
}
func party() {
print("대학생이 파티를 한다.")
}
}
let person1 = Person()
person1.walk()
let student1 = Student()
studetn1.walk()
student1.study()
let undergraduate1 = Undergraduate()
undergraduate1.walk()
undergraduate1.study()
undergraduate1.party()
let student2: Person = Student()
student2.walk()
let undergraduate2: Person = Undergraduate()
undergraduate2.walk()
let people: [Person] = [Person(), Student(), Undergraduate()]
person[0].walk
person[1].walk
person[2].walk
- 업캐스팅된 타입(Person) 형태의 메서드를 호출하더라도,
실제 메모리에서 구현된 "재정의된" 메서드가 호출되어 실행된다.
- 타입의 저장 형태는 속성/메서드에 대한 접근 가능 범위를 나타내는 것이고,
다형성은 인스턴스에서 메모리의 실제 구현 내용에 대한 것.
- 메서드는 재정의 가능하고 메서드 테이블을 통해 동작
Any와 AnyObject를 위한 타입 캐스팅
- Any 타입
- 기본 타입(Int, String, ...) 등 포함, 커스텀 클래스, 구조체, 열거형, 함수 타입까지 포함해서
어떤 타입의 인스턴스도 표현할 수 있는 타입.
- 옵셔널 타입도 가능
- 항상 타입캐스팅 해서 사용해야 한다
- AnyObject 타입
- 어떤 클래스 타입의 인스턴스도 표현할 수 있는 타입
var some: Any = "Swift"
some = 1.0
some = 3.2
var some2: Any = "Hello"
(some2 as! String).count
class Person {
var name = "이름"
var age = 10
}
class Superman {
var name = "이름"
var weight = 100
}
let array: [Any] = [5, "안녕", 3.5, Person(), Superman(), {(name: String) in return name}]
let objArray: [AnyObject] = [Person(), Superman(), NSString()]
(objArray[0] as! Person).name
for (index, item) in array.enumrated() {
switch item {
case is Int:
print("정수입니다")
case let num as Double:
print("소수입니다")
case let String:
print("문자열입니다")
case let person as Person:
print("사람입니다.")
print("이름은 \(person.name) 입니다")
print("나이는 \(person.age) 입니다")
case is (String) -> String:
print("클로저 타입입니다")
default:
print("그 외의 타입입니다.")
}
}