🍃 출처 : 앨런 swift 문법 마스터 스쿨 수업을 듣고 제가 이해한대로 정리해서 올리는 포스팅입니다.
13-2
표현식 is Type
- 인스턴스의 "타입"을 확인 하거나, 해당 인스턴스를 슈퍼 클래스나 하위 클래스로 취급하는 방법
- swift에서 타입 캐스팅은 is 나 as 연산자로 구현하며,
타입 캐스팅을 사용하여 타입이 프로토콜에 적합한지 여부도 확인할 수 있다
: 타입을 체크하는 연산자 (type check operater)
- 참이면 true, 거짓이면 false 리턴
let char: Character = "A" char is Character //true char is String // false
예시1
class Human { }
class Teacher: Human { }
let teacher = Teacher()
teacher is Teacher //true
teacher is Human //ture
- Human 클래스를 Teacher이란 클래스가 상속 받을 경우,
teacher이란 인스턴스는 Human클래스의 서브 클래스이기 때문에,
이런 경우엔 Human으로 타입 체크를 해도 true가 됨
예시2
class Human {
let name: String
init(name: String) {
self.name = name
}
}
class Teacher: Human { }
class Student: Human { }
let people: [Human] = [
Teacher.init(name: "Jess"),
Student.init(name: "Chris")]
for human in people {
if human is Teacher {
print("선생님 : \(human.name)")
} else if human is Student {
print("제자 : \(human.name)")
}
}
// 선생님 : Jess
// 제자 : Chris
예시3
class Person {
var id = 0
var name = "이름"
var email = "abc@gmail.com"
}
class Student: Person {
// id
// name
// email
var studentId = 1
}
class Undergraduate: Student {
// id
// name
// email
// studentId
var major = "전공"
}
let person1 = Person()
person1.id
person1.name
person1.email
let student1 = Student()
student1.id
student1.name
student1.email
student1.studentId // 추가적으로
let undergraduate1 = Undergraduate()
undergraduate1.id
undergraduate1.name
undergraduate1.email
undergraduate1.studentId
undergraduate1.major // 추가적으로
표현식 as (변환 할)Type 표현식 as? (변환 할)Type 표현식 as! (변환 할)Type
- 표현식(의 타입)이 변환할 type과 호환된다면, 변환할 type으로 캐스팅된 인스턴스를 리턴한다.
- 상속관계인 업캐스팅(upcasting)과 다운캐스팅(down casting)에서 사용한다
- Any와 Anyobject 타입을 사용할 경우, 상속관계가 아니어도 예외적으로 사용할 수 있다.
ㅡ
✏️ 업캐스팅(Upcasting)
- 서브 클래스 인스턴스를 "슈퍼클래스의 타입" 으로 참조한다.
- 업 캐스팅은 항상 성공
- 상위 클래스의 메모리 구조로 인식
- 상호 호환 가능한 타입도 항상 성공
예시
class Human {
let name: String
init(name: String) {
self.name = name
}
}
class Teacher: Human { }
class Student: Human { }
let people: [Human] = [
Teacher.init(name: "Jess"),
Student.init(name: "Chris")]
ㅡ
✏️ 다운캐스팅(Downcasting)
- 슈퍼클래스의 인스턴스를 <서브클래스의 타입> 으로 참조한다
- 업캐스팅된 인스턴스를 다시 원래 서브 클래스 타입으로 참조할 때 사용한다
- 다운 캐스팅은 실패할 수 있기에 as?, as! 연산자를 이용한다
예시
class Person {
var id = 0
var name = "이름"
var email = "abc@gmail.com"
}
class Student: Person {
// id
// name
// email
var studentId = 1
}
class Undergraduate: Student {
// id
// name
// email
// studentId
var major = "전공"
}
let person: Person = Person()
person.id
person.name
person.email
//person.studentId // Value of type 'Person' has no member 'studentId'
//person.major // Value of type 'Person' has no member 'major'
// 그런데, 왜 studentId 와 major 속성에는 접근이 되지 않을까? ⭐️
// person2변수에는 Person타입이 들어있다고 인식되는 것임
// ===> 그래서 접근불가 ===> 접근하고 싶다면 메모리구조에 대한 힌트(타입)를 변경 필요
let ppp = person as? Undergraduate // Undergraduate? 타입
// ppp는 옵셔널 Undergraduate
//사용하고 싶다면 if let 바인딩과 함께 사용 (옵셔널 언래핑)
if let newPerson = person as? Undergraduate {
newPerson.major
print(newPerson.major)
}
// 실제로 인스턴스의 접근 범위를 늘려주는 것 뿐임
let person3: Undergraduate = person as! Undergraduate
person3.major
1) 인스턴스 as? 타입
타입캐스팅
- 성공 : Optional 타입으로 리턴 ➡️ 필요한 경우, 언래핑 필요
- 실패 : nil 리턴
2) 인스턴스 as! 타입
타입캐스팅
- 성공 : Optional 타입을 강제 언래핑한 타입
- 실패 : 런타임 오류
ㅡ
13-3
다형성(Polymorphism)
- 하나의 객체(인스턴스)가 여러가지의 타입 형태로 표현될 수 있음
(또는 하나의 타입으로 여러 종류의 객체(인스턴스)를 여러가지 형태(모습)으로 해석될 수 있는 성격)- 다형성은 클래스의 상속(+프로토콜)과 깊은 연관성이 있음
✏️ 상속을 통한 메서드의 재정의와 다형성
- 하나의 인스턴스는 업캐스팅된 타입(Person)으로 인식되고, 호출되더라도
실제 인스턴스 형태(Undergraduate)에 따라 재정의된 메서드가 호출되고 실행
ㅡ
13-4
불특정한 타입을 다룰 수 있는 타입 (범용적인 타입)
1) Any 타입 - 기본 타입(Int, String, Bool, ...) 등 포함, 커스텀 클래스, 구조체, 열거형, 함수타입 까지도 포함해서 어떤 타입의 인스턴스도 표현할 수 있는 타입 (옵셔널타입도 포함) 2) AnyObject 타입 - 어떤 클래스 타입의 인스턴스도 표현할 수 있는 타입 (클래스의 인스턴스만 담을 수 있음)
✏️ switch문과 타입캐스팅 연산자 (타입캐스팅 패턴)
switch item {
case is Int:
print("정수")
case let num as Double:
print("\(num)")
default:
print("그 외의 타입")
}