方法是与特定类型联系的函数。Classes、structures和enumerations能够定义实例方法也能够定义类方法。
一实例方法
实例方法是属于Classes、structures和enumerations实例的方法,它的定义和函数一样。
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.increment(by: 5)
// the counter's value is now 6
counter.reset()
// the counter's value is now 0
The self Property
每一个实例都有一个隐含的属性self,这个 self 指向这个对象本身。
func increment() {
self.count += 1
}
我们可以不写 self,Swift 默认的调用这个实例对象里的方法和属性。
从实例方法内部修该属性值
Structures 和 enumerations是值类型,在默认情况下他们的实例方法不能改变属性值。但是如果你需要在实例方法内部改变属性值,你需要在方法前面加上 mutating关键字。我们甚至可以改变 self 属性,使它变成另外一个实例对象,此时的这个实例的属性无法改变。
struct Point {
var x:Int
var y:Int
mutating func change(point:Point){
self = point;
}
}
var point1 = Point(x: 1, y: 1)
print("\(point1.x) \(point1.y)")
//1 1
var point2 = Point(x: 6, y: 6);
print("\(point2.x) \(point2.y)")
//6 6
point1.change(point2)
print("\(point1.x) \(point1.y)")
//6 6
point2.x = 10
point2.y = 5
print("\(point2.x) \(point2.y)")
//10 5
print("\(point1.x) \(point1.y)")
//6 6
point1.x = 3
point1.y = 3
print("\(point1.x) \(point1.y)")
注意:改变 self 属性时,发生了深拷贝。此时 point1和 point2不是同一个对象
二类型方法
我们可以定义类型方法通过 static 关键字,类型方法属于一个类型。Classes也可以用 class 关键字来容许子类覆盖父类的类型方法。在 OC 中只有 classes 可以定义类型水平的方法,但是在 Swift 中classes, structures, and enumerations都可以定义类型方法。
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod()
注意在类型方法里的 self引用的是类型本身。在一个类型方法内部访问其他类型方法和类型属性可以不加类型名
struct LevelTracker {
static var highestUnlockedLevel = 1
var currentLevel = 1
static func unlock(_ level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) -> Bool {
return level <= highestUnlockedLevel
}
@discardableResult
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}