상속과 타입의 포함관계
class AClass {
var aClassNum: Int = 0
}
class BClass: AClass {
var bClassNum: Int = 1
}
class CClass: BClass {
var cClassNum: Int = 2
}
/*
BClass에는 AClass가 포함돼있고
CClass에는 BClass가 포함돼있다
즉, CClass의 객체를 만들면 AClass와 BClass의 속성에 접근이 가능하다
*/
let cClass: CClass = CClass()
cClass.aClassNum // 0
cClass.bClassNum // 1
cClass.cClassNum // 2
CClass에 BClass와 AClass가 포함돼있고 반대로 AClass에는 BClass나 CClass가 포함돼있지 않다
is 연산자
타입을 체크하는 연산자
class AClass {
var aClassNum: Int = 0
}
class BClass: AClass {
var bClassNum: Int = 1
}
class CClass: BClass {
var cClassNum: Int = 2
}
let aClass: AClass = AClass()
let bClass: BClass = BClass()
let cClass: CClass = CClass()
// AClass 인스턴스는 BClass/CClass의 타입이 아니다 (AClass 타입이다)
aClass is AClass // true
aClass is BClass // false
aClass is CClass // false
// BClass 인스턴스는 CClass의 타입이 아니다 (AClass/BClass 타입이다)
bClass is AClass // true
bClass is BClass // true
bClass is CClass // false
// CClass 인스턴스는 AClass/BClass/CClass 타입이다
cClass is AClass // true
cClass is BClass // true
cClass is CClass // true
인스턴스 생성과 타입
- 부모클래스 타입으로 자식클래스 인스턴스 생성 가능
class AClass {
var aClassNum: Int = 0
}
class BClass: AClass {
var bClassNum: Int = 1
}
class CClass: BClass {
var cClassNum: Int = 2
}
// CClass의 인스턴스를 생성하지만 타입은 AClass
// AClass가 CClass에 포함돼있기 때문에 가능
let cClass: AClass = CClass()
// 타입은 AClass라도 실제 생성된 인스턴스는 CClass의 인스턴스임
cClass is AClass // true
cClass is BClass // true
cClass is CClass // true
// 하지만 타입은 AClass이기 때문에
// AClass의 속성에만 접근 가능
cClass.aClassNum // 0
// cClass.bClassNum (오류)
// cClass.cClassNum (오류)
업캐스팅 (as 연산자)
- 자식클래스의 인스턴스를 부모클래스 타입으로 인식
- 항상 성공
class AClass {
var aClassNum: Int = 0
}
class BClass: AClass {
var bClassNum: Int = 1
}
class CClass: BClass {
var cClassNum: Int = 2
}
let cClass: CClass = CClass() // CClass의 인스턴스
cClass.aClassNum // 0
cClass.bClassNum // 1
cClass.cClassNum // 2
let aClass: AClass = cClass as AClass // 항상 성공
// cClass를 AClass 타입으로 인식
aClass.aClassNum
// AClass의 타입으로 인식되기 때문에
// AClass 하위타입의 속성에는 접근이 불가능
// aClass.bClassNum (오류)
// aClass.cClassNum (오류)
// cClass가 AClass 인스턴스로 변한것이 아닌
// 단순히 AClass 타입으로 인식만 되는것이다
aClass is AClass // true
aClass is BClass // true
aClass is CClass // true
다운캐스팅 (as? / as! 연산자)
- 업캐스팅을 다시 되돌려주는거? 정의를 어찌해야할지 모르겠음
- 다운캐스팅은 업캐스팅이랑 다르게 실패가능성 있음
- as? 연산자
- 다운캐스팅 성공시 옵셔널 타입으로 반환
- 다운캐스팅 실패시 nil 반환
- 언래핑해서 사용
- as! 연산자
- 성공시 옵셔널타입의 값을 강재로 언래핑해서 반환
- 실패시 런타임오류
class AClass {
var aClassNum: Int = 0
}
class BClass: AClass {
var bClassNum: Int = 1
}
class CClass: BClass {
var cClassNum: Int = 2
}
let aClass: AClass = CClass() // AClass 타입의 CClass의 인스턴스
aClass.aClassNum // 0
// aClass.bClassNum (오류)
// aClass.cClassNum (오류)
// as? 연산자는 성공시 옵셔널값 반환
// 언래핑해서 사용
// 실패시 nil 반환
if let cClass: CClass = aClass as? CClass {
cClass.aClassNum // 0
cClass.bClassNum // 1
cClass.cClassNum // 2
cClass is AClass // true
cClass is BClass // true
cClass is CClass // true
}
// as! 연산자는 성공시 옵셔널값 강제 언래핑해서 반환
// 실패시 런타임오류
let cClass2: CClass = aClass as! CClass
cClass2.aClassNum // 0
cClass2.bClassNum // 1
cClass2.cClassNum // 2
cClass2 is AClass // true
cClass2 is BClass // true
cClass2 is CClass // true