实例方法是被某个类型的实例调用的方法,类型方法是定义在类型本身上调用的方法。
实例方法
属于某个特定类、结构体或者枚举类型实例的方法。提供访问和修改实例属性的方法或提供与实例目的相关的功能,并以此来支撑实例的功能。
实例方法能够隐式访问它所属类型的所有的其他实例方法和属性。只能被它所属的类的某个特定实例调用,并且不能脱离于现存的实例而被调用。
class Counter {
var count = 0
//实例方法
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset(){
count = 0
}
}
let counter = Counter()
counter.increment() //起始值是0,现在是1
counter.increment(by: 5) //现在是6
counter.reset() //现在是0
self属性
使用 self 属性来区分参数名称和属性名称。
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
return self.x > 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
}
说明:如果不使用 self 前缀,Swift会认为 x 的两个用法都引用了名为 x 的方法参数。
在实例方法中修改值类型(mutating)
默认情况下,值类型的属性不能在它的实例方法中被修改。
但是,如果确实需要在某个特定的方法中修改结构体或者枚举的属性,可以为这个方法选择可变(mutating)行为,然后就可以从其方法内部改变它的属性;并且这个方法做的任何改变都会在方法执行结束时写回到原始结构中。方法还可以给它隐含的 self 属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。
struct Point1 {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint1 = Point1(x: 1.0, y: 1.0)
somePoint1.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint1.x), \(somePoint1.y))") //3.0,4.0
注:不能在结构体类型的常量上调用可变方法,因为其属性不能被改变,即使属性是变量属性.
在可变方法中给 self 赋值
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() //high
ovenLight.next() //off
类型方法
在方法的 func 关键字之前加上关键字 static,来指定类型方法。类还可以用关键字 class 来指定,从而允许子类重写父类该方法的实现。
struct LevelTracker {
static var highestUnlockedlevel = 1
var currentLevel = 1 //玩家进度
//新等级被解锁,更新 highestUnlockedlevel
static func unlock(_ level: Int) {
if level > highestUnlockedlevel {
highestUnlockedlevel = level
}
}
//给定等级已解锁,返回true
static func isUnlocked(_ level: Int) -> Bool {
return level <= highestUnlockedlevel
}
//更新前检查新等级是否解锁
@discardableResult //允许在调用 advance(to:) 时候忽略返回值,不会产生编译警告
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
}else {
return false
}
}
}
//Player 类使用 LevelTracker 来监测和更新每个玩家的发展进度
class Player {
var tracker = LevelTracker()
let palyerName: String
func complete(level: Int) {
LevelTracker.unlock(level + 1)
tracker.advance(to: level + 1)
}
init(name: String){
palyerName = name
}
}
var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedlevel)") //2
player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
print("player is now on level 6")
}else{
print("level 6 has not yet been unlocked")
}