類的繼承與初始化
1.所有類的存儲屬性(包括從他的父類繼承的所有屬性)都必須在初始化期間分配初始值
2.Swift為類類型定義了兩種初始化器以確保所有的存儲屬性接收一個初始值。 這些就是所謂的指定初始化器和便捷初始化器
3.指定初始化器是類的主要初始化器。指定的初始化器可以初始化所有那個類引用的屬性并且調用合適的父類初始化器來繼續這個初始化過程給父類鏈
4.類偏向于少量指定初始化器,并且一個類通常只有一個指定初始化器。
5.每個類至少需要得有一個指定初始化器。
6.便捷初始化器是次要的。如果你不需要便捷初始化器你可以不提供他。
"""
//初始化器會在創建特性類型的實例時被調用
struct CustomStruct {
var name: String
init() {
name = "Eddiegooo"
}
}
var cs = CustomStruct()
print(cs) //CustomStruct(name: "Eddiegooo")
//默認屬性初始化器
struct MyCustomStruct {
var name = "Eddiegooo"
}
var myCS = MyCustomStruct()
print(myCS) //MyCustomStruct(name: "Eddiegooo")
//也可以修改默認屬性
var mycs = MyCustomStruct(name: "Chole")
print(mycs)
//swift為所有沒有提供默認初始化器的結構體或類提供了一個默認初始化器來給所有的屬性提供默認值
class DefaultClass {
var name: String?
var age: Int = 1
var isMan = false
}
var dClass = DefaultClass()
//自定義初始化器. 傳自己的參數,可以定義多個
//值類型的初始化器委托 —— 初始化器可以調用其他初始化器來執行部分實例初始化。避免了多個初始化器里冗余代碼
struct Celsius {
var temprature: Double
init(fromHuashi temp: Double) {
temprature = temp - 32
}
init(fromKelvin kelvin: Double) {
temprature = kelvin - 273.0
}
}
let huaTemp0 = Celsius(fromHuashi: 212.0)
let kelTemp0 = Celsius(fromKelvin: 273.0)
//在初始化的任何時刻都可以給常量屬性賦值,一旦被賦值,就不可以在被修改
class Question {
let text: String
var resuest: String?
init(text: String) {
self.text = text
}
func ask() {
print(text)
}
}
let q = Question(text: "How Old are U")
q.ask()
//如果結構體類型中沒有定義任何類型的初始化器,它會自動獲得一個成員初始化器。
struct Size {
var width = 0, height = 0
}
let size = Size(width: 3, height: 5)
"""
指定初始化器必須從他的直系父類調用指定初始化器
便捷初始化器必須從相同的類里調用另一個初始化器
便捷初始化器最終必須調用一個指定初始化器
"""
//指定初始化器與便捷初始化器(用convenience 修飾init)
//init(params) {
//// statements
//}
//convenience init(params) {
//// statements
//}
//Swift 兩段式初始化 —— 使初始化更加安全。還可以防止屬性值在初始化之前被訪問,還可以防止屬性值被另一個初始化器意外的賦予不同的值
//Swift 初始化安全檢查
//1.指定初始化器必須x保證向上委托給父類初始化之前,其所在類引入的所有屬性都要初始化完成
//2.指定初始化器必須s向上委托父類初始化器。然后才能為繼承的屬性設置新值。 否則,指定初始化器賦予的新值將被父類中的初始化器覆蓋
//3.便捷初始化器必須委托同類中的其他初始化器,然后再為任意屬性賦新值。 否則,便捷初始化器賦予的新值將被自己類中其他指定初始化器所覆蓋
//4.初始化器在第一階段完成之前,不能調用任何實例方法、不能讀取任何實例屬性的值,也不能引用self作為值。
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
convenience init() {
self.init(name: "[Unnamed]", age: 0)
}
}
class Teacher: Person {
var salary: Int
// init(name: String, age: Int, salary: Int) {
// super.init(name: name, age: age)
// self.salary = salary //報錯了,違背安全檢查第一條,salary沒有被初始化在調用super之前, 因此要放在super之前。。
// }
// init(name: String, age: Int, salary: Int) {
// self.salary = salary
// self.name = name + "Teacher" //報錯,違背安全檢查第二條。 這個要放在super之后
// super.init(name: name, age: age)
// }
// init(name: String, age: Int, salary: Int) {
// self.salary = salary
// self.testFunc() //報錯,違背安全檢查第四條 'self' used in method call 'testFunc' before 'super.init' call
// super.init(name: name, age: age)
// self.name = name + "Teacher"
// }
init(name: String, age: Int, salary: Int) {
self.salary = salary
super.init(name: name, age: age)
self.name = name + "Teacher"
self.testFunc()
}
// convenience init(name: String) {
// self.name = name + "Teacher" //違背安全檢查第三條 'self' used before 'self.init' call or assignment to 'self'
// self.init(name: name, age: 30, salary: 5000)
// }
convenience init(name: String) {
self.init(name: name, age: 30, salary: 5000)
}
func testFunc() -> Void {
print("U are a Teacher")
}
}
初始化器兩個階段
階段一.png
階段二.png
自動繼承
繼承與從寫
初始化器自動繼承.png
//初始化器的繼承與重寫
//Swift的子類不會默認繼承父類的初始化器。 只有在特定情況才會繼承
//必要初始化器 在前面加required 所有該類的子類都必須實現該初始化器
class Person {
var age: Int
var name: String
required init(name: String, age: Int) {
self.age = age
self.name = name
}
}
class Teacher: Person {
required init(name: String, age: Int) {
super.init(name: name, age: age)
}
}
//可失敗的初始化器 init?
class Person {
var age: Int
var name: String
init?(name: String, age: Int) {
if age > 100 {
return nil
}
self.age = age
self.name = name
}
}
//反初始化 —— 在類實例被釋放的時候,反初始化器就會立即被調用 反初始化器只在類類型中有效 deinit
//反初始化器會在實例被釋放之前自動被調用,你不能自行調用反初始化器。
//每個類中只能有一個反初始化器。不接受任何形式參數,不用圓括號
//deinit {
//
//}
反初始化器.png
繼承
Swift里沒有通用的基類, 不在繼承于其他的類都可以稱為基類
重寫父類override. 訪問父類使用super。 也可以重寫getter setter。
阻止重寫加final
class Vehicle {
var currentSpeed: Int = 0 //這里不賦默認值,會提示你沒有初始化
final var name: String = "Father"
var description: String {
return "run at \(currentSpeed)"
}
func makeNoise() {
}
}
class Car: Vehicle {
var gear: Int = 0
override var description: String {
return super.description + "at gear \(gear)"
}
override var name: String { //報錯 Cannot override mutable property with read-only property 'name'
return super.name + "erzi"
}
override func makeNoise() {
print("tutututut")
}
}
var car = Car()
car.gear = 30
print(car.description)
重寫相關
擴展
擴展不可以重寫已有的方法。
擴展可以向已有的類型添加新的初始化器。
擴展能為類添加新的便捷初始化器,但是不能添加指定初始化器和反初始化器。
extension Double {
var km: Double {
return self / 1000
}
}
extension Int {
func repeatTask(_ task: ()->()) {
for _ in 0..<self {
task()
}
}
}
3.repeatTask {
print("Hello world")
}
//擴展下標
extension Int {
subscript(index: Int) -> Int {
get {
var base = 1
for _ in 0..<index {
base *= 10
}
return base
}
}
}