Swift中的类
类如果没有给属性提供初始值,则必须提供构造函数
类是引用类型
要改变自身,需要加上mutating
关键字,但对于类不需要这么做。
enum Switch{ case On case Off mutating func click(){ switch self { case .On: self = .Off case .Off: self = .On } } } var button = Switch.Off button.click()
类的等价
默认情况下 ==
不能用于类的实例对象的比较
===
用于判断两个对象的等价性 !==
判读不等于
什么时候使用类?什么时候使用结构体?
1.结构体===值;类===物体 结构体是值类型,类是引用类型
2.结构体不可被继承;类可以被继承
3.结构体更加轻量级,小规模的类建议使用结构体
4.结构体较为高效,原因:结构体的内存空间在栈,类的内存空间在堆.堆中查找地址速度较慢
属性和方法
计算属性
例如中心点的坐标是根据原点和Size计算出来的,当origin和size发生变化时,那么center则对应的要发生变化
struct Point{ var x = 0.0 var y = 0.0 } struct Size { var width = 0.0 var height = 0.0 } class Rectangle { var origin = Point() var size = Size() var center: Point{ let centerX = origin.x + size.width / 2 let centerY = origin.y + size.height / 2 return Point(x: centerX,y: centerY) } init(origin: Point,size: Size){ self.origin = origin self.size = size } }
计算型属性的声明要注意:
1.必须声明为var
2.必须显式声明类型,不能省略
3.默认是只读属性,让计算型的属性可以赋值,可以如下处理
var center: Point{ get{ let centerX = origin.x + size.width / 2 let centerY = origin.y + size.height / 2 return Point(x: centerX,y: centerY) } set(newCenter){ origin.x = newCenter.x - size.width / 2 origin.y = newCenter.y - size.height / 2 } }
在上述的代码中,setter方法可以不声明newCenter
,使用默认值newValue
set{ origin.x = newValue.x - size.width / 2 origin.y = newValue.y - size.height / 2 }
类型属性
如下记录游戏的最高分static var highestscore = 0
class Player{ var name: String var score = 0 static var highestscore = 0 init(name: String){ self.name = name } func play(){ let score = random() % 100 self.score += score if self.score > Player.highestscore { Player.highestscore = self.score } } }
类型方法
属性观察器
class LightBulb{ static let maxCurrent = 30 var current = 0 { // 可以不声明新的变量名,使用newValue willSet(newCurrent){ // 此时,current还是以前的值 print("Current value changed. The change is \(abs(current-newCurrent))") } // property observer可以用来限制值或者格式 // 也可以用来做关联逻辑 // 可以不声明新的变量名,使用oldValue获取原来的值 didSet(oldCurrent){ // 此时,current已经是新的值 if current == LightBulb.maxCurrent{ print("Pay attention,the current value get to the maximum point.") } else if current > LightBulb.maxCurrent{ print("Current too high,falling back to prevIoUs setting.") current = oldCurrent } print("The current is \(current)") } } } let bulb = LightBulb() bulb.current = 20 bulb.current = 30 bulb.current = 40
输出结果为:
Current value changed. The change is 20 The current is 20 Current value changed. The change is 10 Pay attention,the current value get to the maximum point. The current is 30 Current value changed. The change is 10 Current too high,falling back to prevIoUs setting. The current is 30
注意didSet
和willSet
不会在初始化阶段init
和设置默认值调用
延迟属性
// 最佳方案,使用懒加载 lazy var sum: Int = { //print("start computing sum value") var res = 0 for i in self.start...self.end{ res += i } return res }()
继承
使用final
,阻止进一步继承
final class Magician: User { var magic = 100 }