類(lèi)
使用class后跟類(lèi)的名稱(chēng)來(lái)創(chuàng)建類(lèi)厌小。 類(lèi)中的屬性聲明的寫(xiě)法與常量或變量聲明相同筛欢。 同樣浸锨,方法和函數(shù)聲明的寫(xiě)法也是一樣的。
class Shape {
var numberOfSides = 0 //屬性
func simpleDescription() -> String {//無(wú)參數(shù)有返回值得方法
return "A shape with \(numberOfSides) sides."
}
}
通過(guò)在類(lèi)名稱(chēng)后面添加括號(hào)來(lái)創(chuàng)建類(lèi)的實(shí)例版姑。 使用點(diǎn)語(yǔ)法訪問(wèn)實(shí)例的屬性和方法柱搜。
var shape = Shape() //實(shí)例化了一個(gè)Shape的對(duì)象
shape.numberOfSides = 7 //使用點(diǎn)語(yǔ)法訪問(wèn)類(lèi)的屬性
var shapeDescription = shape.simpleDescription()//使用點(diǎn)語(yǔ)法調(diào)用類(lèi)的方法
如果我們想要在初始化的時(shí)候給類(lèi)的屬性賦值或者調(diào)用方法,那我們需要自己用init來(lái)創(chuàng)建初始化方法
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String){
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
deinit {
print("對(duì)象要被釋放了剥险,在這里做一些處理")
}
}
- 注意:如何使用self來(lái)區(qū)分name屬性和name參數(shù)在初始化方法中聪蘸。 初始化方法的參數(shù)在創(chuàng)建類(lèi)的實(shí)例時(shí)像一個(gè)函數(shù)調(diào)用一樣傳遞。 每個(gè)屬性都需要一個(gè)賦值的值表制,無(wú)論是在聲明中(如numberOfSides)還是在初始化方法中(和name一樣)健爬。
- 如果需要在釋放對(duì)象之前執(zhí)行一些清理,請(qǐng)使用deinit創(chuàng)建一個(gè)deinitializer夫凸。
- 子類(lèi)在類(lèi)名之后包括它們的父類(lèi)名,用冒號(hào)分隔阱持。 任何根類(lèi)不需要類(lèi)來(lái)子類(lèi)化夭拌,因此您可以根據(jù)需要包括或省略父類(lèi)類(lèi)。
- override關(guān)鍵字,標(biāo)志著這個(gè)方法是從父類(lèi)繼承過(guò)來(lái)的鸽扁,子類(lèi)重寫(xiě)了蒜绽,父類(lèi)的方法,但是他并沒(méi)有取代父類(lèi)中的方法桶现。
class Square: NamedShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name) //調(diào)用父類(lèi)的初始化方法去初始化name
numberOfSides = 4
}
func area() -> Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {//重寫(xiě)了父類(lèi)的方法
return "A square with sides of length \(sideLength)."
}
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
屬性的getter和setter
除了存儲(chǔ)的簡(jiǎn)單屬性之外躲雅,屬性還可以有一個(gè)getter和setter。
class EquilateralTriangle: NamedShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return 3.0 * sideLength
}
set {
sideLength = newValue / 3.0
}
}
override func simpleDescription() -> String {
return "An equilateral triangle with sides of length \(sideLength)."
}
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)/調(diào)用get方法
triangle.perimeter = 9.9//調(diào)用set方法
print(triangle.sideLength)
在swift中骡和,系統(tǒng)會(huì)自動(dòng)給我們生成一個(gè)隱式的變量名叫“newValue”相赁,我們也可以自己聲明一個(gè)顯示的變量名
var perimeter: Double {
get {
return 3.0 * sideLength
}
set (perimeter){//顯示的名稱(chēng)
sideLength = perimeter / 3.0
}
}
注意 EquilateralTriangle類(lèi)的初始化有三個(gè)不同的步驟:
- 設(shè)置子類(lèi)聲明的屬性的值。
- 調(diào)用父類(lèi)的初始化方法慰于。
- 更改由父類(lèi)定義的屬性的值钮科。 使用方法,getter或setter的任何額外的設(shè)置工作也可以在這一點(diǎn)上完成婆赠。
willSet绵脯、didSet
如果不需要計(jì)算屬性,但仍需要提供在設(shè)置新值之前和之后運(yùn)行的代碼休里,請(qǐng)使用willSet和didSet蛆挫。 您提供的代碼在值在初始值之外更改時(shí)運(yùn)行。 例如妙黍,下面的類(lèi)確保其三角形的邊長(zhǎng)總是與其正方形的邊長(zhǎng)相同悴侵。
class TriangleAndSquare {
var triangle: EquilateralTriangle {
willSet {
square.sideLength = newValue.sideLength
}
}
var square: Square {
willSet {
triangle.sideLength = newValue.sideLength
}
}
init(size: Double, name: String) {
square = Square(sideLength: size, name: name)
triangle = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)
可選值
使用可選值時(shí),在“废境?” 之前的操作畜挨,如方法,屬性和下標(biāo)噩凹。 如果“巴元?”之前的值是nil,那么“驮宴?”之后的將會(huì)被忽略逮刨,整個(gè)表達(dá)式的值為nil。 否則堵泽,可選值被展開(kāi)修己,并且之后的所有內(nèi)作用于展開(kāi)的值。 在這兩種情況下迎罗,整個(gè)表達(dá)式的值都是可選值睬愤。
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength