Swift3.x - 类和结构体

类的介绍和定义

  • Swift也是一门面向对象的开发语言。
  • 面向对象的基础就是类,类产生对象。
  • Swift如何定义类:
    • class关键字定义类
    class 类名: SuperClass {
          //定义属性和方法
    

}

* 使用注意:
* 定义类的时候,可以没有父类,那么该类就是根类
* 通常情况下定义定义类时,继承自NSObject

**如何定义类的属性**
* Swift中类的属性有多种:
* 存储属性:存储实例的常量和变量
* 计算属性:通过某种方式计算出来的属性
* 类属性:与整个类相关的属性
* 存储属性
  ```
  class person: NSObject{
      //存储属性
      var age = 0
      var name: String?
  }

  let child = person()
  child.age = 18
  child.name = "小明"

  if let name = child.name {
      print("\(name)今年\(child.age)了")
  }
  //结果:小明今年18了
  ```
* 计算属性
在类中声明的计算属性,这个属性可以由类中定义的函数来完成,但是苹果官方并不见这种实现方式,因为计算属性的方式更加简单明了,下面就来实现以下某个人的在某段时间内完成跑步的平均时速。

class person: NSObject{

  var time = 2
  var startSpeed = 10.0
  var hightSpeed = 20.0
  var endSpeed = 5.0

   //推荐
   var averageSpeed: Double {
       return (startSpeed + hightSpeed + endSpeed) * 0.5
   }
   //不推荐
   func averageSpeedFunction() -> Double {
      return (startSpeed + hightSpeed + endSpeed) * 0.5
  }

}

let child = person()
child.averageSpeedFunction()
child.averageSpeed

* 类属性
类属性是和整个类相关的属性,而且是通过类名来访问。常见于单例!

class person: NSObject{

  //定义某个人有书籍的数量
  static var book = 0

}

person.book = 2
//结果:2

**类的构造函数**
* 构造函数
  * 构造函数类似于OC中的初始化方法:init方法
  * 默认情况下创建某个类时,必然会调用一个构造函数
  * 即便开发者没有构建构造函数,编译器也会提供默认的构造函数
  * 如果继承自NSObject可以对父类的构造函数进行重写
* 构造函数的基本使用
  * 类的属性必须有值
  * 如未在定义时初始化值,可以在构造函数中赋值,通过传递参数,初始化类对象。
      ```
      class person: NSObject{
  
          var name: String?
          var height = 0.0
          //重写父类的构造方法
          //如果重写父类的构造方法,在实例化此类时,Xcode会提示这个方法,如果未重写,Xcode只会提示,我们自定义的构造方法!
          override init(){
              super.init()
          }
          //自定义构造方法
          init(name: String, height: Double) {
              self.name = name
              self.height = height
          }
  
      }

      let child = person(name: "小明", height: 1.88)
      child.name
      child.height
      //结果:小明 1.88
      ```
  * 通过字典参数实例化类对象
    ```
      class person: NSObject{
  
      var name: String?
      var height = 0.0
      //重写父类的构造方法
      override init(){
           super.init()
      }
       //自定义构造方法
      init(name: String, height: Double) {
           self.name = name
           self.height = height
      }
  
      init(dict: [String : AnyObject]) {
             //此种写法会报错,因为从字典中取出的值为AnyObject?可选类型,直接赋值会报错!
             //self.name = dict["name"]
             //self.height = dict["height"]

             //解决方法1:
             //as? 转换符 将as?左侧的类型转换成as?右侧的类型的可选类型
             name = dict["name"] as? String
             //as! 转换符 将as!左侧的类型转换成as! 右侧的类型的可选类型
             height = dict["height"] as! Double
             //但是此种写法同时有带来了新的问题,强制解包是很危险的操作,会造成程序crash
              
             //解决方法2:
             name = dict["name"] as? String
             //可选绑定
             if let tempHeight = dict["height"] as? Double {
                    height = tempHeight
             }
       }
      }
      let child = person(dict: ["name":"小明" as AnyObject, "height": 1.90 as AnyObject])
    ```
    利用KVC实现构造函数实现
    ```
        class person: NSObject{
  
        var name: String?
        var height = 0.0
        //重写父类的构造方法
        override init(){
            super.init()
        }
        //自定义构造方法
        init(name: String, height: Double) {
            self.name = name
            self.height = height
        }
        //KVC
        init(dict: [String : AnyObject]) {
            super.init()
            setValuesForKeys(dict)
        }
        //防止传入的字典存在未知的键值->报错
        override func setValue(_ value: Any?, forUndefinedKey key: String) {}
    }
    let child = person(dict: ["name":"小明" as AnyObject, "height": 1.90 as AnyObject, "weight": 100 as AnyObject])
    child.name
    child.height
    //结果:小明 1.9
    ```

**类的属性监听器**
* 在OC中我们可以重写set方法来监听属性的改变
* Swift中可以通过属性观察者来监听和响应属性的改变
* 通常监听存储属性和类属性
* 通过设置以下方法来定义观察者
  * willSet:将在属性值即将改变时调用
  * didSet:将在属性值改变后调用
  class person: NSObject{

  var name: String?{
      willSet{
          print("\(name)")
      }
    
      didSet{
          print("\(name)")
      }
  }

}
let child = person()
child.name = "小明"


**结构体的介绍和定义**
结构体与类存在很多共同点:
* 定义属性用于存储值
* 定义方法用于提供功能
* 定义下标操作使得可以通过下标语法来访问实例所包含的值
* 定义构造器用于生成初始化值
* 通过扩展以增加默认实现的功能
* 实现协议以提供某种标准功能

* Swift中如何定义结构体:
  * struct关键字定义结构体

struct 结构体名{
//结构体属性or方法
}


**结构体实例化**
结构体实例化和类实例化非常相似:

struct SomeStruct{
//结构体属性or方法
var width = 0
var height = 0
}
//实例化结构体
var someStruct = SomeStruct()

在Swift中,结构体可以直接修改结构体的子属性的值,这点是与OC不同之处!

import UIKit

struct SomeStruct{
//结构体属性or方法
var width = 0
var height = 0
}

var someStruct = SomeStruct()
someStruct.height = 100
someStruct.height
//结果:someStruct.height值为100

**结构体的逐一构造器**
结构体存在逐一构造器,而类中默认是不存在的!我们可以自定义构造函数来完成逐一构造器,上述类的自定义构造方法其实就是自定义的逐一构造器方法!

struct SomeStruct{
//结构体属性or方法
var width = 0
var height = 0
}

var someStruct = SomeStruct(width: 66, height: 88)
someStruct.height
//结果:88
someStruct.width
//结果:66

**结构体与类之间的选择**

�结构体总是通过值传递(值类型),类总是通过引用传递(引用类型)!
按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:
* 该数据结构的主要目的是用来封装少量相关简单数据值。
* 有理由预计该数据结构的实例在被赋值或传递时,封装的数据将会被拷贝而不是被引用。
* 该数据结构中储存的值类型属性,也应该被拷贝,而不是被引用。
* 该数据结构不需要去继承另一个既有类型的属性或者行为。

######注意:
在Swift中字符串、数组、字典均为结构体的形式实现(OC中均为类的形式实现)。拷贝行为看起来似乎总会发生。然而,Swift 在幕后只在绝对必要时才执行实际的拷贝。Swift 管理所有的值拷贝以确保性能最优化,所以你没必要去回避赋值来保证性能最优化。

Zeb
参考地址:https://github.com/numbbbbb/the-swift-programming-language-in-chinese
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容