Swift:類與物件
Classes and Objects
github:Swift基礎例項
github:SwiftBasicTableView
- 類的建立
使用關鍵字class
,後面跟上類名稱,來建立一個類。
class Shape {
var numberOfSides = 0
let numberOfPoint = 3
func simpleDescription() ->String {
return "A shape with \(numberOfSides) sides"
}
func simplePoint(point:Int) ->Int {
return point
}
}
通過在類名後加圓括號()
來建立類的例項。用點語法(dot syntax),也就是物件加點呼叫
來訪問例項中的屬性和方法:
var shape = Shape()
shape.numberOfSides = 1
var shapeDes = shape.simpleDescription()
print(shapeDes)
- 構造器
上面的類Shape
少了一個重要的東西:當一個例項被建立的時候,用來構造這個類的初始化方法(可以稱為構造器
)。用init
來生成一個這樣的方法:
class NameShape {
var numberOfSides: Int = 0
var name :String
init(name:String) {
self.name = name
}
func simpleDescription() ->String {
return "A shape with a name \(name)"
}
}
var nameShape = NameShape(name: "ssss")
var initName = nameShape.simpleDescription()
- 在建立類的例項的時候,它的一個屬性
name
在初始化方法中被初始化 - 每一個屬性如果不是可選型別(加
?
進行宣告),都 必須 賦值---無論是numberOfSides
還是初始化方法中的name
- 析構器
在物件釋放時,可以在析構器中做些清理工作,用關鍵字deinit
來生成一個析構器:
class NameShapeTwo {
var numberOfSides: Int
init(number:Int) {
print("init called")
self.numberOfSides = number
}
deinit {
print("deinit called")
numberOfSides = 0
}
func addNumbers(number:Int) {
numberOfSides += 3
}
}
var shapeTwo :NameShapeTwo? = NameShapeTwo(number: 3)
print("numberOfSides : \(shapeTwo!.numberOfSides)")
shapeTwo = nil
- 輸出順序為:
init called numberOfSides : 3 deinit called
- 類的繼承
子類包含父類的名字,用冒號:
將子類名和父類名隔開。如果子類要重寫/使用 父類已經定義過的方法,子類 必須 在該方法前加override
關鍵字,如果不寫override
編譯器會報錯。而且編譯器還會檢測那些帶有override
的方法,判斷這些方法是否是真的重寫父類中的方法:
class Square: NameShape {
var sideLength: Double
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
func area() ->Double {
return sideLength * sideLength
}
override func simpleDescription() -> String {
return "A square with sides of length \(sideLength)."
}
}
var squareTest = Square(sideLength: 3.2, name: "subclass test")
squareTest.area() //10.24
squareTest.simpleDescription() //"A square with sides of length 3.2."
squareTest.name //"subclass test"
同時需要注意:1.子類可以設定自己宣告的屬性 2.子類可以改變在父類中定義的屬性; 3.子類可以呼叫父類的方法,比如上面構造器方法 init;
- getter 和 setter
除了儲存屬性,其它屬性可以有一個getter
和一個setter
方法
class EquilateralTriangle: NameShape {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) {
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get {
return sideLength*3.0
}
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) //"9.3"
triangle.perimeter = 9.9
print(triangle.sideLength) //"3.3"
- 在
perimeter
的setter
方法中,perimeter
的新值有個預設名字newValue
,你也可以在set
之後明確的指定一個名字,把名字放在()
中,例如:set(perimeter) { sideLength = perimeter / 3.0}
。 - 從上面的
get
與set
方法和OC
的方法有很大的區別,我們可以試著和OC
"相似"的方法來實現sideLength
的get
與set
方法:
class EquilateralTriangleOne: NameShape {
init(sideLength: Double, name: String) {
self.tempLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var tempLength: Double = 0.0
var sideLength: Double {
get {
print("getget")
return self.tempLength
}
set {
print("setset")
self.tempLength = newValue
}
}
override func simpleDescription() -> String {
return "An equilateral triangle with sides of length \(self.sideLength)."
}
}
var triangleOne = EquilateralTriangleOne(sideLength: 3.5, name: "b triangle")
print(triangleOne.sideLength) // getget 3.5
triangleOne.sideLength = 3.6 // setset
print(triangleOne.sideLength) // getget 3.6
- willSet 和 didSet
如果你不需要計算一個屬性,但是仍需要在這個屬性被設定新值之前
和之後
,執行一些程式碼(暫且稱為程式碼A),那麼可以使用willSet
和didSet
。在 構造器 之外,只要這個屬性的值發生改變,程式碼A 都會被執行,類似觀察者模式中的property observe
:
class TriangleAndSquare {
var triangleL: EquilateralTriangle {
willSet {
print("triangleL willSet")
squareL.sideLength = newValue.sideLength
}
didSet {
print("triangleL didSet")
}
}
var squareL: Square {
willSet {
print("squareL willSet")
triangleL.sideLength = newValue.sideLength
}
didSet {
print("squareL didSet")
}
}
init(size: Double, name:String) {
// 少初始化任何一個物件,都會報錯
// return from initializer without initializing all stored properties
// 類似於 oc 的用來儲存資料的 model,需要物件序列化一樣
squareL = Square(sideLength: size, name: name)
triangleL = EquilateralTriangle(sideLength: size, name: name)
}
}
var triangleAndSquare = TriangleAndSquare(size: 5.0, name: "another shape")
print(triangleAndSquare.squareL.sideLength) // 5.0
print(triangleAndSquare.triangleL.sideLength) // 5.0
triangleAndSquare.squareL = Square(sideLength: 10.0, name: "lager shape") //squareL willSet squareL didSet
print(triangleAndSquare.triangleL.sideLength) // 10.0
- 注意上面的註釋部分
- 操作符
?
用操作符?
來表示一個值是可選的,如果?
前面的值是nil
,那麼?
後面的所有操作都會被忽視,然後這個表示式的值會變為nil
:
let optionalSquare : Square? = Square(sideLength:5.3, name: "optionalSquare")
var optionalLength = optionalSquare?.sideLength
- 如果
optionalSquare
為nil
,那麼就不會呼叫sideLength
,optionalLength
的值變為nil
相關文章
- Swift通過類名建立物件Swift物件
- 物件與類物件
- 類與物件物件
- ⦁ 類與物件物件
- Swift 類與結構體Swift結構體
- Swift,結構體與類Swift結構體
- 類與物件3物件
- OC:類與物件☀️物件
- swift物件導向特性——類和結構體Swift物件結構體
- Java物件導向——類與物件Java物件
- Java-物件與類Java物件
- php.類與物件PHP物件
- JavaFX教程-類與物件Java物件
- Java - 11 類與物件Java物件
- 類與物件的建立物件
- 類與物件的概念物件
- python物件導向思想(類與物件)Python物件
- 【騏程】Java類與物件Java物件
- java中的類與物件Java物件
- synchronized類鎖與物件鎖synchronized物件
- 實驗2 類與物件物件
- Java語言之物件導向—類與物件(上)Java物件
- Python基礎-類與物件Python物件
- Python中的類與物件Python物件
- 談談java的類與物件Java物件
- 課時36:類與物件:給大家介紹物件物件
- Swift,類的呼叫Swift
- iOS Swift結構體與類的方法排程iOSSwift結構體
- 課時38:類與物件:繼承物件繼承
- 課時39:類與物件:拾遺物件
- 第八章類與物件物件
- 物件與類_知識點筆記物件筆記
- Java中的類與物件詳解Java物件
- 課時37:類與物件:物件導向程式設計物件程式設計
- Java中類與物件的關係與區別Java物件
- swift 物件儲存地址分析Swift物件
- 談談我對物件導向以及類與物件的理解物件
- python中物件導向_類_物件的概念與定義Python物件