类的定义
类定义的关键字是 class
,我们用 class
+ 类名 + ":" + 父类,比如定义一个 Person
类,类中去声明和定义变量和函数:
class Person: NSObject {
var name: String
public func sayHello(){
print("Hello ~")
}
}
复制代码
类的扩展
extension Person { // 给人加一个飞的功能...
func fly() {}
}
复制代码
属性
存储属性
存储属性就是存储在类或者结构体一个实例里的一个常量和变量,用 var
或者 let
修饰。
但是如果一个结构体实例被声明为常量,那么即便这个结构体的某个属性是变量,也是不能去改变的:
let point = CGPoint(x: 1, y: 1)
point.x = 10 // 编译是不会通过的
复制代码
延迟存储属性
lazy var nameLabel:UILabel = {
let label = UILabel()
// ...
return label
}()
复制代码
其实就是把一个立即执行的闭包的返回值赋值给属性,以达到懒加载的目的。
属性观察器
willSet
在新的值被设置之前调用 didSet
在新的值被设置之后立即调用 需要注意的是:当为存储型属性设置默认值或者在构造器中为其赋值时,它们的值是被直接设置的,不会触发任何属性观察者。
计算属性
计算属性提供了一个 getter
和一个可选的 setter
。属性的 getter
和 setter
的关键词是 get
和 set
,在 setter
中新值是 newValue
class Person: NSObject {
var birthYear: Int
var age : Int{
set{
self.age = newValue
self.birthYear = 2016 - newValue
}
}
}
复制代码
只读计算属性
当一个属性只有 getter
而没有 setter
时,那么它就是一个只读计算属性
类对象的实例和访问:
var person = Person()
person.age = 10
复制代码
类的构造和析构
我们可以给 Person
自定义一个构造函数,构造函数中需要给所有的存储型属性一个赋值或者默认值:
init(name: String) {
self.name = name
}
复制代码
这样我们就可以用 name
来实例化一个对象: var person = Person(name:"Tom")
如果所有属性都有默认值,我们没有自定义的构造,系统会生成一个默认的构造函数:var person = Person()
相应的,如果我们自定义了一个构造函数,那么系统便不会为该类生成默认的构造函数。 但是,我们可以把自定义的构造函数写到类的扩展(extension
)里,而不是类的原始定义里面。
与构造函数对应的是析构函数:deinit
指定构造器和便利构造器 指定构造器里面会初始化类实例所有的属性,所以为了保证继承的属性也能被初始化,子类的指定构造器都会调用父类的指定构造器,而类的便利构造器总是会调用本类的指定构造器。 也就是说:指定构造器需要向上调用,便利构造器需要横向调用
所以,我们可以把父类的指定构造函数重写成便利构造,却不能重写父类的便利构造。即便重写了父类的便利构造函数,但是由于我们不能直接调用父类的便利构造函数,所以不用给函数以 override
修饰。
必要构造器 如果某个构造函数被 required
修饰,那么该函数就是必要构造函数,子类继承该类时都必须要实现改构造函数。在子类重写父类的构造函数的时候,也要加 required
来修饰,以确定继承链上子类的子类也遵守。
除了构造和析构函数,类还有实例的私有函数、公共函数和静态函数。
类、函数的访问控制(访问、继承/重载 权限)
Swift
中的访问控制有 模块 和 源文件 两个概念。用 "import" 导入的就是模块。
对于类而言的修饰词与权限:
修饰词 | 权限 |
---|---|
open | 修饰的类可以随意继承与访问 |
public | 修饰的类只能在本模块内被继承,但是可以随便访问 |
internal | 默认 - 模块内拥有访问权限 |
fileprivate | 是文件外部不能被访问 |
private | 是文件内部不能被访问 |
final | 是文件内部也不能被继承 |
当然了,对于一个 internal
的类,其属性和方法的级别是不会超出类本身的,比如不可能是 public
。
函数也是同样的修饰词和权限,只是类的继承对应函数的重载权限。 函数除了以上几个,常用的修饰词还有 static
和 override
。
static
修饰的是类方法。override
修饰的是重写父类的方法。
我的博客:iosgg.cn/