Swift:類與對象

Classes and Objects

github:Swift基礎實例
github:SwiftBasicTableView

  1. 類的創(chuàng)建
    使用關鍵字 class 淫半,后面跟上類名稱右钾,來創(chuàng)建一個類。
class Shape {
    var numberOfSides = 0
    let numberOfPoint = 3
    func simpleDescription() ->String {
        return "A shape with \(numberOfSides) sides"
    }
    func simplePoint(point:Int) ->Int {
        return point
    }
}

通過在類名后加圓括號() 來創(chuàng)建類的實例竣灌。用點語法(dot syntax),也就是對象加點調用 來訪問實例中的屬性和方法:

var shape = Shape()
shape.numberOfSides = 1
var shapeDes = shape.simpleDescription()
print(shapeDes)
  1. 構造器
    上面的類 Shape 少了一個重要的東西:當一個實例被創(chuàng)建的時候冠场,用來構造這個類的初始化方法(可以稱為構造器)秆剪。用 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()
  • 在創(chuàng)建類的實例的時候赊淑,它的一個屬性name在初始化方法中被初始化
  • 每一個屬性如果不是可選類型(加 ? 進行聲明),都 必須 賦值---無論是 numberOfSides 還是初始化方法中的 name
  1. 析構器
    在對象釋放時仅讽,可以在析構器中做些清理工作陶缺,用關鍵字 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
  1. 類的繼承
    子類包含父類的名字,用冒號 : 將子類名和父類名隔開洁灵。如果子類要重寫/使用 父類已經定義過的方法饱岸,子類 必須 在該方法前加 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百框;

  1. 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"
  • perimetersetter 方法中牍汹,perimeter的新值有個默認名字 newValue铐维,你也可以在 set 之后明確的指定一個名字,把名字放在()中慎菲,例如:set(perimeter) { sideLength = perimeter / 3.0}嫁蛇。
  • 從上面的 getset方法和 OC 的方法有很大的區(qū)別,我們可以試著和 OC "相似"的方法來實現 sideLengthgetset方法:
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
  1. willSet 和 didSet
    如果你不需要計算一個屬性钧嘶,但是仍需要在這個屬性被設置新值 之前之后棠众,執(zhí)行一些代碼(暫且稱為代碼A)琳疏,那么可以使用 willSetdidSet有决。在 構造器 之外,只要這個屬性的值發(fā)生改變空盼,代碼A 都會被執(zhí)行书幕,類似觀察者模式中的 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
  • 注意上面的注釋部分
  1. 操作符?
    用操作符? 來表示一個值是可選的台汇,如果 ? 前面的值是 nil,那么 ? 后面的所有操作都會被忽視,然后這個表達式的值會變?yōu)?nil:
let optionalSquare : Square? = Square(sideLength:5.3, name: "optionalSquare")
var optionalLength = optionalSquare?.sideLength
  • 如果 optionalSquarenil苟呐,那么就不會調用sideLength痒芝,optionalLength的值變?yōu)?nil
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市牵素,隨后出現的幾起案子严衬,更是在濱河造成了極大的恐慌,老刑警劉巖笆呆,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件请琳,死亡現場離奇詭異,居然都是意外死亡赠幕,警方通過查閱死者的電腦和手機俄精,發(fā)現死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榕堰,“玉大人竖慧,你說我怎么就攤上這事【直” “怎么了测蘑?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長康二。 經常有香客問我碳胳,道長,這世上最難降的妖魔是什么沫勿? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任挨约,我火速辦了婚禮,結果婚禮上产雹,老公的妹妹穿的比我還像新娘诫惭。我一直安慰自己,他們只是感情好蔓挖,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布夕土。 她就那樣靜靜地躺著,像睡著了一般瘟判。 火紅的嫁衣襯著肌膚如雪怨绣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天拷获,我揣著相機與錄音篮撑,去河邊找鬼。 笑死匆瓜,一個胖子當著我的面吹牛赢笨,可吹牛的內容都是我干的未蝌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼茧妒,長吁一口氣:“原來是場噩夢啊……” “哼萧吠!你這毒婦竟也來了?” 一聲冷哼從身側響起桐筏,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤怎憋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后九昧,有當地人在樹林里發(fā)現了一具尸體绊袋,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年铸鹰,在試婚紗的時候發(fā)現自己被綠了癌别。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹋笼,死狀恐怖展姐,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情剖毯,我是刑警寧澤圾笨,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站逊谋,受9級特大地震影響擂达,放射性物質發(fā)生泄漏。R本人自食惡果不足惜胶滋,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一板鬓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧究恤,春花似錦俭令、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至理张,卻和暖如春赫蛇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涯穷。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工棍掐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留藏雏,地道東北人拷况。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓作煌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赚瘦。 傳聞我的和親對象是個殘疾皇子粟誓,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容