Swift-属性、方法

153 阅读4分钟

1.属性

1.1存储属性(Stored Property)

1)类似于成员变量;
2)存储在实例的内存中;
3)结构体、类中可以定义存储属性;枚举不可以定义存储属性;
4)存储属性可以声明为var、let;当存储属性所在class、struct声明为let时,即使存储属性为var,也不可更改;

1.2计算属性

1)本质是方法(函数);
2)不占用实例的内存;
3)枚举、结构体、类都可以定义计算属性;
4)计算属性可以只有get,没有set;但是不能只有set;有set必须有get 5)计算属性只能是var,不能是let 举个🌰:

struct Circle{
    //存储属性
    var radius : Double
    //计算属性
    var diameter : Double{
        set{
            radius = newValue / 2
        }
        get{
            radius * 2
        }
    }
    //set传入的新值默认叫做newValue,也可以自定义
var reDiameter : Double{
        set(newDiameter){
            radius = newDiameter / 2
        }
        get{
            radius * 2
        }
    }
}

1.3延迟存储属性

类似于懒加载:在第一次用到属性的时候才会进行初始化;

主要格式:lazy var property name = expression

lazy var name : String = {
    return "just a  example"
}()

附加:
1)lazy属性必须是var,不能是let;let必须在实例的初始化方法完成之前赋值;
2)多线程同时第一次访问lazy属性,无法保证属性只被初始化1次;
3)当结构体包含一个延迟存储属性时,只有var才能访问延迟存储属性;

1.4属性观察器

1)可以为非lazy的var存储属性设置属性观察器;
2)willSet默认参数为newValue;didSet默认参数为oldValue;
3)willSet在存储新值之前调用;didSet在存储新值之后调用;

struct Circle{
    var radius : Double{
        willSet{
            print("willSet",newValue)
        }
        didSet{
            print("didSet",oldValue,radius)
        }
    }
    init(){
        self.radius = 1.0
        print("Circle init!")
    }
}

附加:
1)在初始化器中设置属性值不会触发willSet和didSet;
2)在属性定义时设置初始值也不会触发willSet和didSet;
3)父类的属性在它自己的初始化器中赋值不会触发属性观察器,但在子类的初始化器中赋值会触发属性观察器; 举个🌰:

struct Point{
    var x : Int = 0
    var y : Int = 0
}
//等价于
struct Point{
    var x : Int
    var y : Int
    init(){
        self.x = 0
        self.y = 0
    }
}

更改为属性观察模式:

struct Point{
    var x : Int = 0 {
        willSet{
            print("willSet",newValue)
        }
        didSet{
            print("didSet",oldValue,x)
        }
    }
}
//等价于
struct Point{
    var x : Int{
        willSet{
            print("willSet",newValue)
        }
        didSet{
            print("didSet",oldValue,x)
        }
    }
    init(){
        self.x = 0
    }
}

两个定义方式是等价的,都不触发willSet&didSet方法。

1.5类型属性

struct Point{
    static var x : Int = 0//类型属性
}
var point = Point.x
point = 30
print(point)

附加:
1)只能通过类去访问;
2)存储类型属性:整个程序运行过程中,就只有1份内存(类似于全局变量);
3)可以通过static定义类型属性;
4)必须给存储类型属性设定初始值;
5)存储类型属性默认是lazy,会在第一次使用的时候才初始化;
6)枚举类型也可以定义类型属性(存储类型属性、计算类型属性);

2.方法

1)枚举、结构体、类都可以定义实例方法、类型方法;
2)实例方法(Instance Method):通过实例对象调用;
3)类型方法(Type Method):通过类型调用,用static或者class关键字定义;类的计算属性可以使用class关键字声明,这样可以允许子类重写父类实现;
4)self:在实例方法中代表实例对象;在类型方法中代表类型;

3.继承

值类型不支持继承,只有类支持继承;
子类可以继承父类的方法和属性;Swift中称为重写(override)。

3.1 重写属性

1)子类可以重写父类的下标、方法、属性,重写必须加上override关键字;
2)被class修饰的类型方法、下标,允许被子类重写;被static修饰的类型方法、下标,不允许被子类重写。
3)子类可以将父类的属性(存储、计算)重写为计算属性;不可以将父类属性重写为存储属性。
4)只能重写var属性,不能重写let属性;重写时,属性名、类型要一致。
5)子类重写后的属性权限,不能小于父类属性的权限;

3.2 重写类型属性

1)被class修饰的计算类型属性,可以被子类重写;
2)被static修饰的类型属性(存储、计算),不可以被子类重写;

3.3 自动继承

1)如果子类没有自定义任何初始化方法,它会自动继承父类所有的初始化方法(包括便利初始化方法);
2)子类可以以便利初始化方法重写父类的初始化方法;
3)用required修饰初始化方法,表明其所有子类都必须实现该初始化方法;子类重写了required初始化方法是,也必须加上required,不用加override