微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift中的类

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

注意didSetwillSet不会在初始化阶段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

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐