類的繼承與初始化
1.所有類的存儲屬性(包括從他的父類繼承的所有屬性)都必須在初始化期間分配初始值
2.Swift為類類型定義了兩種初始化器以確保所有的存儲屬性接收一個初始值。 這些就是所謂的指定初始化器和便捷初始化器
3.指定初始化器是類的主要初始化器。指定的初始化器可以初始化所有那個類引用的屬性并且調(diào)用合適的父類初始化器來繼續(xù)這個初始化過程給父類鏈
4.類偏向于少量指定初始化器,并且一個類通常只有一個指定初始化器。
5.每個類至少需要得有一個指定初始化器。
6.便捷初始化器是次要的戒突。如果你不需要便捷初始化器你可以不提供他。
"""
//初始化器會在創(chuàng)建特性類型的實(shí)例時被調(diào)用
struct CustomStruct {
var name: String
init() {
name = "Eddiegooo"
}
}
var cs = CustomStruct()
print(cs) //CustomStruct(name: "Eddiegooo")
//默認(rèn)屬性初始化器
struct MyCustomStruct {
var name = "Eddiegooo"
}
var myCS = MyCustomStruct()
print(myCS) //MyCustomStruct(name: "Eddiegooo")
//也可以修改默認(rèn)屬性
var mycs = MyCustomStruct(name: "Chole")
print(mycs)
//swift為所有沒有提供默認(rèn)初始化器的結(jié)構(gòu)體或類提供了一個默認(rèn)初始化器來給所有的屬性提供默認(rèn)值
class DefaultClass {
var name: String?
var age: Int = 1
var isMan = false
}
var dClass = DefaultClass()
//自定義初始化器. 傳自己的參數(shù)描睦,可以定義多個
//值類型的初始化器委托 —— 初始化器可以調(diào)用其他初始化器來執(zhí)行部分實(shí)例初始化膊存。避免了多個初始化器里冗余代碼
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()
//如果結(jié)構(gòu)體類型中沒有定義任何類型的初始化器隔崎,它會自動獲得一個成員初始化器。
struct Size {
var width = 0, height = 0
}
let size = Size(width: 3, height: 5)
"""
指定初始化器必須從他的直系父類調(diào)用指定初始化器
便捷初始化器必須從相同的類里調(diào)用另一個初始化器
便捷初始化器最終必須調(diào)用一個指定初始化器
"""
//指定初始化器與便捷初始化器(用convenience 修飾init)
//init(params) {
//// statements
//}
//convenience init(params) {
//// statements
//}
//Swift 兩段式初始化 —— 使初始化更加安全韵丑。還可以防止屬性值在初始化之前被訪問爵卒,還可以防止屬性值被另一個初始化器意外的賦予不同的值
//Swift 初始化安全檢查
//1.指定初始化器必須x保證向上委托給父類初始化之前,其所在類引入的所有屬性都要初始化完成
//2.指定初始化器必須s向上委托父類初始化器撵彻。然后才能為繼承的屬性設(shè)置新值钓株。 否則,指定初始化器賦予的新值將被父類中的初始化器覆蓋
//3.便捷初始化器必須委托同類中的其他初始化器陌僵,然后再為任意屬性賦新值轴合。 否則,便捷初始化器賦予的新值將被自己類中其他指定初始化器所覆蓋
//4.初始化器在第一階段完成之前碗短,不能調(diào)用任何實(shí)例方法受葛、不能讀取任何實(shí)例屬性的值,也不能引用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 //報(bào)錯了总滩,違背安全檢查第一條,salary沒有被初始化在調(diào)用super之前巡雨, 因此要放在super之前闰渔。。
// }
// init(name: String, age: Int, salary: Int) {
// self.salary = salary
// self.name = name + "Teacher" //報(bào)錯铐望,違背安全檢查第二條澜建。 這個要放在super之后
// super.init(name: name, age: age)
// }
// init(name: String, age: Int, salary: Int) {
// self.salary = salary
// self.testFunc() //報(bào)錯向挖,違背安全檢查第四條 '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")
}
}
初始化器兩個階段
自動繼承
//初始化器的繼承與重寫
//Swift的子類不會默認(rèn)繼承父類的初始化器蝌以。 只有在特定情況才會繼承
//必要初始化器 在前面加required 所有該類的子類都必須實(shí)現(xiàn)該初始化器
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
}
}
//反初始化 —— 在類實(shí)例被釋放的時候炕舵,反初始化器就會立即被調(diào)用 反初始化器只在類類型中有效 deinit
//反初始化器會在實(shí)例被釋放之前自動被調(diào)用,你不能自行調(diào)用反初始化器跟畅。
//每個類中只能有一個反初始化器咽筋。不接受任何形式參數(shù),不用圓括號
//deinit {
//
//}
繼承
Swift里沒有通用的基類徊件, 不在繼承于其他的類都可以稱為基類
重寫父類override. 訪問父類使用super奸攻。 也可以重寫getter setter。
阻止重寫加final
class Vehicle {
var currentSpeed: Int = 0 //這里不賦默認(rèn)值虱痕,會提示你沒有初始化
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 { //報(bào)錯 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)
擴(kuò)展
擴(kuò)展不可以重寫已有的方法睹耐。
擴(kuò)展可以向已有的類型添加新的初始化器。
擴(kuò)展能為類添加新的便捷初始化器部翘,但是不能添加指定初始化器和反初始化器硝训。
extension Double {
var km: Double {
return self / 1000
}
}
extension Int {
func repeatTask(_ task: ()->()) {
for _ in 0..<self {
task()
}
}
}
3.repeatTask {
print("Hello world")
}
//擴(kuò)展下標(biāo)
extension Int {
subscript(index: Int) -> Int {
get {
var base = 1
for _ in 0..<index {
base *= 10
}
return base
}
}
}