方法是关联了特定类型的函数,用来封装特定的任务和功能。Swift中的类,结构体和枚举都可以定义方法。
1. 实例方法
实例方法 是属于特定类实例、结构体实例或者枚举实例的函数。
- 要写一个实例方法,需要把它放在对应类的花括号之间
- 实例方法默认可以访问同类下所有其他实例方法和属性
- 实例方法只能在类型的具体实例里被调用,不能在独立于实例而被调用
举个栗子:
class Counter {
var count = 0
func increment() { // 实例方法 1
count += 1
}
func increment(by amount: Int) { // 实例方法 2
count += amount
}
func reset() { // 实例方法 3
count = 0
}
}
调用实例方法,仍然使用点语法:
let counter = Counter()
// 初始化时count值为 0
counter.increment()
// 现在count值为 1
counter.increment(by: 5)
// 现在count值为 6
counter.reset()
// 现在count值为 0
self 属性
每一个类的实例都隐含一个叫做self
的属性,它完全与实例本身相等。可以使用self
属性直接调用它自身的方法,如上面的increment
方法可以写成:
func increment() {
self.count += 1
}
如果你没有显式地写出
self
,Swift默认调用当前实例中的属性或者方法。但属性名和实例方法参数名相同时,省略self指的是实例方法参数,加上self则指的是属性。
如:
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
return self.x > x // self.x 指的是Point类的属性 x
// 后面的x值得是函数isToTheRightOf中的参数 x
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
print("This point is to the right of the line where x == 1.0")
}
// 结果为: "This point is to the right of the line where x == 1.0"
在实例方法中修改值类型
结构体和枚举是值类型。默认情况下,值类型属性不能被自身的实例方法修改。但是,如果需要在特定的方法中修改结构体或者枚举的属性,可以选择将这个方法异变(mutating):
struct Point {
var x = 0.0, y = 0.0
// 在func关键字前添加mutating表明这是一个异变方法
mutating func moveByX(deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0) // 注意这里的somePoint必须是变量
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// 结果为: "The point is now at (3.0, 4.0)"
注意,我们不能在常量结构体类型里调用异变方法,因为常量结构人自身属性不能被改变,即使它们是变量属性:
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// 这里将会报错
在异变方法里指定自身
异变方法可以指定整个实例给隐含的self
属性。上文中的栗子可以用下边的代码代替:
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
再举个枚举的栗子:
enum TriStateSwitch {
case off, low, high
mutating func next() {
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight 现在为 .high
ovenLight.next()
// ovenLight 现在为 .off
2. 类型方法
在类型本身调用的方法称作类型方法。
- 可以通过在
func
关键字之前使用static
关键字来明确一个类型方法 - 类同样可以使用
class
关键字来允许子类重写父类对类型方法的实现
语法如下:
class SomeClass {
class func someTypeMethod() {
// 方法实现部分
}
}
// 调用类型方法
SomeClass.someTypeMethod()
注意: 在类型方法的函数体中,隐含的
self
属性指向了类本身而不是这个类的实例。