Swift:面向对象(属性)

厍和颂
2023-12-01

本人录制技术视频地址:https://edu.csdn.net/lecturer/1899 欢迎观看。

Swift中属性的用法比objective-c中属性的用法丰富了很多。下面我逐一介绍。

一、 存储属性 和 延迟存储属性

Demo如下:

class Dog {
    var name = "旺财"
    init(){
        println("狗被初始化了")
    }
}

class Person {
    let age = 20
    var name = "Jack"
    var height = 0.0
    
    lazy var dog = Dog()
}

var p = Person()
p.dog

代码中,定义了Dog和Person两个类。

1. Dog中的name属性和Person中的age,name,height均为存储属性,用来存储对象的普通属性值。

2. Person中的dog属性,它也是存储属性,只不过它的属性值是Dog对象,而dog属性前面又有了lazy关键字修饰,它就成为了延迟存储属性。

3. 延迟存储属性:第一次用到的时候才初始化,不能作用于常量上面,一般作用于对象上面。上面代码 var p = Person()执行完毕后,dog属性并没有被初始化。当执行完p.dog后,dog才被初始化一个Dog对象。

二、 计算属性

Swift中的计算属性,很类似与C#中的get;set;属性。

Demo如下(计算正方形周长);

class Square {
    var width: Double = 10
    var grith: Double {
        get{
            return width * 4
        }
        set{
            width = newValue / 4
        }
    }
}

var s = Square()
s.width         // 10
s.grith     		// 40
s.grith = 100   // width : 25

上例中,width表示正方形的边长,它是存储属性;而grith表示正方形的周长,它是计算属性;而grith这个计算属性中有get和set两个方法,get表示根据边长可以计算出周长;而set表示根据周长可以计算出边长。需要说明的是set方法中的newValue就是外界赋值给girth传递过来的值,比如上面的s.grith = 100 执行后,newValue的值就是100;而这个newValue值是系统默认的变量,我们也可以自己定义变量,如下:

class Square {
    var width: Double = 10
    var grith: Double {
        get{
            return width * 4
        }
        set(myValue){
            width = myValue / 4
        }
    }
}

注:存储属性必须对属性进行数据初始化操作(除非使用了构造方法,下一节进行讲解);而计算属性可以借助存储属性进行一些计算操作,而得到最终的结果。

三、 类型属性

类型属性简称类属性。

1. 只能是计算属性。

2. 不管创建多少个实例,这些实例共享一份资源。

class Square {
    class var PI: Double{
        return 3.14
    }
}

println("PI的值:\(Square.PI)")

如上例中,PI就是类型属性,它是用class关键字修饰的。并且调用的时候,直接"类名.属性名" 就可以了。而上述中的类型属性是简写形式,我们也可以写成:

class Square {
    class var PI: Double{
        get{
            return 3.14
        }
    }
}
四、 属性监视器

1. 如果是计算属性,直接在set方法中监听即可,类似于objective-c中的kvo方式监听属性。

2. 如果是存储属性,我们需要使用willSet和didSet进行监视。

Demo如下:

class Square {
    var width: Double = 0.0 {
        willSet{
            println("New Value:\(newValue), Current Value:\(width)")
        }
        didSet{
            println("Old Value:\(oldValue), Current Value:\(width)")
        }
    }
}

var s = Square()
s.width = 100

willSet和didSet在属性初始化过程中不会被调用。当执行到代码s.width = 100 的时候,会触发willSet和didSet这两个方法,最终结果为:

New Value:100.0, Current Value:0.0
Old Value:0.0, Current Value:100.0

五、属性重写

可以将一个继承来的只读属性重写为一个读写属性。

class Animal {
    var speed: Int {
        get {
            return 100
        }
    }
}

class Dog: Animal {
    override var speed: Int {
        get {
            return 300
        }
        set {
            
        }
    }
}

不可以将一个继承来的读写属性重写为一个只读属性(下面的代码,Dog类会报错)

class Animal {
    var speed: Int {
        get {
            return 100
        }
        set {
        
        }
    }
}

class Dog: Animal {
    override var speed: Int {
        get {
            return 100
        }
    }
}

存储属性的重写(最终属性的值是存储在父类中的)

class Animal {
    var speed: Int = 0 {
        willSet {
            println("Animal - willSet")
        }
        didSet {
            println("Animal - didSet")
        }
    }
}

class Dog: Animal {
    override var speed: Int {
        willSet {
            println("Dog - willSet")
        }
        didSet {
            println("Dog - didSet")
        }
    }
}

var d = Dog()
d.speed = 10
最终打印结果
Dog - willSet
Animal - willSet
Animal - didSet
Dog - didSet

 类似资料: