swift의 상속은 클래스, 프로토콜에서 가능하다.
enum과 struct는 상속이 불가하다.
swift는 다중 상속을 지원하지 않는다
어떤 키워드로 상속을 막고 푸는지 알아보자.
class Person{
var name: String = " "
func selfIntroduce(){
print("저는 \(name)입니다")
}
// final 키워드: 재정의 방지
final func sayHello(){
print("hello")
}
// static 키워드: 재정의 불가
static func typeMethod(){
print("type method - static")
}
//class: 재정의 가능 타입 메서드
class func classMethod(){
print("type method - class")
}
//class도 final키워드를 사용하면 재정의할 수 없다.
final class func finalClassMethod(){
print("type method - final class")
}
}
class Student: Person{
var major: String = ""
override func selfIntroduce(){
print("저는 \(name)이고, 전공은 \(major)입니다")
}
override class func classMethod(){
print("overriden type method - class")
}
}
static을 사용한 타입 메서드는 재정의할 수 없다.
final 키워드를 사용한 메서드와 프로퍼티는 재정의할 수 없다.
let dora: Person = Person()
let hana: Student = Student()
dora.name = "dora"
hana.name = "hana"
hana.major = "Swift"
dora.selfIntroduce()
hana.selfIntroduce()
Person.classMethod()
Person.typeMethod()
Person.finalClassMethod()
Student.classMethod()
Student.typeMethod()
Student.finalClassMethod()
옵셔널 체이닝은 옵셔널 요소 내부의 프로퍼티로 또 다시 옵셔널이 연속적으로 연결되는 경우 유용하게 사용할 수 있다.
프로퍼티를 타고 타고 들어가야 할 때,
옵셔널인 경우 계속 nil인지 체크해야하기 때문에 유용하게 옵셔널 체이닝을 쓸 수 있다
class Person{
var name: String
var job: String
var home: Apartment?
init(name: String){
self.name = name
}
}
class Apartment{
var buildingNumber: String
var roomNumber: String
var `guard`: Person?
var owner: Person?
init(dong: String, ho: String){
buildingNumber = dong
roomNumber = ho
}
}
let dora: Person? = Person(name: "dora")
let apart: Apartment? = Apartment(dong: "101", ho: "202")
let superman: Person? = Person(name: "superman")
옵셔널 체이닝 실행 후, 결과값이 nil일 수 있으므로 결과 타입도 옵셔널이다.
만약 옵셔널 체이닝을 사용하지 않는다면
func guardJob(owner: Person?){
if let owner = owner{
if let home = owner.home{
if let `guard` = home.guard{
if let guardJob = `guard` .job{
print("우리집 경비원의 직업은 \(guardJob)입니다")
}else{
print("우리집 경비원은 직업이 없어요.")
}
}
}
}
}
guardJob(owner: dora)
옵셔널 체이닝을 사용한다면?
func guardJobWithOptionalChaining(owner: Person?){
if let guardJob = owner? .home? .guard? .job{
print("우리집 경비원의 직업은 \(guardJob)입니다")
}else{
print("우리집 경비원은 직업이 없어요")
}
}
guardJobWithOptionalChaining(owner: dora)
dora?.home?.guard?.job
dora?.home = apart
dora?.home
dora?.home?.guard
dora?.home?.guard = superman
dora?.home?.guard
dora?.home?.guard?.name
dora?.home?.guard?.job
dora?.home?.guard?.job = "경비원"
//nil 병합 연산자
var guardJob: String
guardJob = dora?.home?.guard?.job ?? "슈퍼맨"
print(guardJob)
dora?.home?.guard?.job = nil
guardJob = dora?.home?.guard?.job ?? "슈퍼맨"
print(guardJob)