类,引用类型,用class关键字声明
先来声明一个类
class Person{
var name:String?//这种不用写init
var age:Int!//这种不用写init
}
这里注意,属性有几种写法
var name:String = "ref"
var age:Int = 12//这种,有初始值,可以不用写init
如果是这样就要写init,不写会报错,这点跟结构体不一样
class Person{
var name:String
var age:Int
//这里,必须写init
init(name:String, age:Int) {
self.name = name
self.age = age
}
}
接下来我们介绍一下类中的类型属性,类型方法
class Person{
var name:String
var age:Int
static var country:String?//static关键字声明类属性和类方法
init(name:String, age:Int) {
self.name = name
self.age = age
}
func text(){
print(Person.country)//注意用法,类属性,要用类来调用,这个属性,属于类,而不属于类实例出来的对象
}
}
let p = Person(name: "re", age: 16)
p.text()//调用对象方法
类型方法,就是OC里边的+号方法,写法如下
static func text_classFunction(){
print(Person.country)
}
调用是这样
Person.text_classFunction()
下边,我们来说说存储属性和计算属性
存储属性,就是用来存储一个类型的具体对象,一般我们model里边的都是存储属性
计算属性,就是要经过逻辑计算得到的数据,计算属性必须是可变的(var)
class point{
//存储属性
var point_x:CGFloat = 0
var point_y:CGFloat = 0
}
我们现在有一个需求,给出一个point可以得到centerPoint,当然我们可以写一个方法,如果我们能写一个属性,他会根据point_x和point_y来动态的计算,我们只需要点出这个属性就可以,这就有了计算属性
class Point{
//存储属性
var point_x:CGFloat = 0
var point_y:CGFloat = 0
//计算属性
var centerPoint:(CGFloat, CGFloat){//这里,我用一个元组来接收结果,默认是get-only的属性
let x = point_x/2
let y = point_y/2
return (x,y)
}
}
可以这样调用
let po = Point()
po.point_x = 12.6
po.point_y = 5.8
po.centerPoint
这时,如果你想给centerPoint赋值,像这样
po.centerPoint = (23.4, 45.6)//会报错,说centerPoint是get-only属性
这时,就需要写set方法了,是不是跟OC很像?
//计算属性
var centerPoint:(CGFloat, CGFloat){
//如果写了set就必须要写get,
set{
self.centerPoint = newValue//newValue是系统默认给的,当然你也可以自己定义:set(newCenterPoint){}
}
get{
let x = point_x/2
let y = point_y/2
return (x,y)
}
}
这样,你就可以个centerPoint赋值了,不过想一下,如果计算属性可以外部直接改变,那为何我不直接写一个存储属性呢?我想,这也是系统默认只读的原因吧
最后,我们再来说说属性观察器
如果你想要在赋值之前,判断一下数据是否有效,就需要属性观察器
class LightBulb{
static let maxCurrent = 30
var current = 0 {
didSet{
//这里,current已经是新的值了
if current == LightBulb.maxCurrent {
print("数据到临界值了")
}
else if (current > LightBulb.maxCurrent){
current = oldValue
print("数据太大了")
}
print(current)
}
willSet(newCurrent){
print(newCurrent)
}
}
}
属性观察器,一目了然,无需多言,需要注意一点,初始化的时候,didSet是不会调用的。
网友评论