21강 상속
// 스위트프 상속은 클래스, 프로토콜에서만 가능
// 다중상속은 지원하지 않음
import Swift
class Person {
var name: String = ""
func selfIntroduce() {
print("저는 \(name)입니다.")
}
// final 키워드를 사용하여 재정의하지 못하도록함
final func sayHello() {
print("hello")
}
// 자식클래스에서 재정의 불가능함
static func typeMethod() {
print("type method - statid")
}
// 자식클래스에섯 재성의 가능
class func classMethod() {
print("type method - class")
}
// 재정의 가능한 class 클래스라도 final 키워드를 사용하면 재정의 할 ㅜㅅ 없음
final class func finalClassMethod() {
print("type method - final class")
}
}
class Student: Person {
// 상속해서 받은 거기때문에 없어도 상관없음
//var name: String = ""
var major: String = ""
override func selfIntroduce() {
print("저는 \(name)이고, 전공은 \(major)입니다.")
}
override class func classMethod() {
print("overried class method")
}
}
let yagom: Person = Person()
let hana: Student = Student()
yagom.name = "yagom"
hana.name = "hana"
hana.major = "Swift"
yagom.selfIntroduce()
hana.selfIntroduce()
Person.classMethod()
Student.classMethod()
22강 인스턴스 생성/소멸
// 모든 인스턴스는 초기화와 동씨에 모든 프로터피에 유효 값이 할당되어 있어야함
// 프로퍼티에 미리 기본값을 할당하면 인스턴스가 생성됨과 동시에 초기값을 가지게됨
class PersonB {
var name: String
var age: Int
var nickName: String
init(name: String, age: Int, nickName: String){
self.name = name
self.age = age
self.nickName = nickName
}
}
class PersonC {
var name: String
var age: Int
var nickName: String? //프러퍼티의 초기값이 꼭 필요없는 경우
convenience init(name: String, age: Int, nickName: String){
self.init(name: name, age: age)
self.nickName = nickName
}
init(name: String, age: Int){
self.name = name
self.age = age
}
}
let zoe: PersonB = PersonB(name: "zoe", age: 20, nickName: "zoe")
let kkk: PersonC = PersonC(name: "kkk", age: 10)
// 암시적 추출 옵셔널
class Puppy {
var name: String
var owner: PersonC! // 인스턴스 사용에 꼭 필요하지만 초기값 할당하지 않는 경우
init(name: String) {
self.name = name
}
func goOut() {
print("\(name)가 주인 \(owner.name)와 산책합니다.")
}
}
let happy: Puppy = Puppy(name: "happy")
happy.owner = kkk
happy.goOut()
// 실패가능한 이니셜라이저
class PersonD {
var name: String
var age: Int
var nickName: String?
init?(name: String, age: Int){
if (0...120).contains(age) == false {
return nil
}
// characters' is unavailable: Please use String directly
if name.count == 0 {
return nil
}
self.name = name
self.age = age
}
}
let john: PersonD? = PersonD(name: "john", age: 23)
let error: PersonD? = PersonD(name: "", age:130)
print(john)
print(error)
// 디이니셜라이저
// class 인스턴스가 메모리에서 해제되는 시점에 호출됨
// 인스턴스 해제되는 시점에 해야할일을 구현 가능
class PersonE {
var name: String
var pet: Puppy?
var child: PersonC
init(name:String, child: PersonC){
self.name = name
self.child = child
}
deinit {
if let petName = pet?.name {
self.pet?.owner = child
print("\(name)가 \(child.name)에게 \(petName)를 인도합니다")
}
}
}
var donald: PersonE? = PersonE(name: "donald", child: kkk)
donald?.pet = happy
donald = nil
23강 옵셔널 체이닝과 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 yagom: Person? = Person(name: "yagom")
let apart: Apartment? = Apartment(dong: "101", ho: "202")
let superman: Person? = Person(name: "superman")
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: yagom)
func guardJobWithOptionalChaining(owner: Person?) {
if let guardJob = owner?.home?.guard?.job {
print("우리집 경비원의 직업은 \(guardJob)")
}else{
print("우리집 경비원은 직업이 없어요")
}
}
guardJobWithOptionalChaining(owner: yagom)
var guardJob: String
// 앞에 값이 nil 이면 슈퍼맨 출력
guardJob = yagom?.home?.guard?.job ?? "슈퍼맨"
print(guardJob)
24강 타입 캐스팅
// 인스턴슷의 타입을 확인하는 용도
// 클래스의 인스턴스를 부모, 자식 클래스 타입으로 사용할 수 있는지 확인하는 용도
class Person {
var name: String = ""
func breath() {
print(" 숨을쉽니다.")
}
}
class Studnet: Person {
var school: String = ""
func goToSchool() {
print("등교를 합니다.")
}
}
class UniversityStudent: Studnet {
var major: String = ""
func goToMT() {
print("멤버쉽 트레이닝을 갑니다. ")
}
}
var yagom: Person = Person()
var hana: Studnet = Studnet()
var jason: UniversityStudent = UniversityStudent()
var result: Bool
// True (상속 받았기 때문에)
result = hana is Person
// 업 캐스팅
// 부모클래스의 인스턴스를 사용할 수 있도록 컴파일러에 정보를 알려주는 것
// person 행세 할 수 있도록 업캐스팅
var mike: Person = UniversityStudent() as Person
var jina: Any = Person() // as Any (생략)
// 다운캐스팅
// 자식 클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 인스턴스 타입정보 전환해줌
var optitonalCasted: Studnet?
optitonalCasted = mike as? UniversityStudent
optitonalCasted = jina as? UniversityStudent
// 강제 다운 캐스팅 - 무조건 이 역할을 하도록
optitonalCasted = mike as! UniversityStudent
// optitonalCasted = jina as! UniversityStudent 런타임오류