结构体和枚举能够定义方法是 Swift 与 C/Objective-C 的主要区别之一。在 Objective-C 中,类是唯一能定义方法的类型。但在 Swift 中,你不仅能选择是否要定义一个类/结构体/枚举,还能灵活的在你创建的类型(类/结构体/枚举)上定义方法。
⦿ 实例方法
实例方法是属于某个特定类、结构体或者枚举类型实例的方法。实例方法提供访问和修改实例属性的方法或提供与实例目的相关的功能,并以此来支撑实例的功能。实例方法的语法与函数完全一致.
实例方法要卸载它所属的类型的前后大括号之间.实例方法能够隐式访问它所属类型的所有的其他实例方法和属性,实例方法只能被它所属的类的某个特定实例调用.实例方法不能脱离于现存的实例而被调用.
/*
//MARK: -- self属性(The self Property)
*/
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOfx(x: Double) -> Bool {
return self.x > x //只有在实例方法的某个参数名和实例的某个属性名称相同的时候参数名有优先权,此时必须使用self.x > x ,来区分属性名和参数名,如果该情况下不使用self,Swift就会认为两次使用的x都值得是名称为x的函数参数
}
}
//MARK: -- 在实例方法中修改值类型
//结构体和枚举是值类型。一般情况下,值类型的属性不能在它的实例方法中被修改。但是,如果你确实需要在某个具体的方法中修改结构体或者枚举的属性,你可以选择变异(mutating)这个方法,然后方法就可以从方法内部改变它的属性;并且它做的任何改变在方法结束时还会保留在原始结构中。方法还可以给它隐含的self属性赋值一个全新的实例,这个新实例在方法结束后将替换原来的实例。
struct Point2 {
var x = 0.0, y = 0.0
mutating func moveByx(deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
//变异方法能够赋值给隐含属性self一个全新的实例.上面的两个等式也可以写成
// self = Point2(x: x + deltaX, y: y + deltaY)
}
}
//MARK: -- 枚举的变异方法可以吧self设置为相同的枚举类型中不同的成员:
enum TriStateSwitch {
case Off,Low,High
mutating func next() {
switch self {
case .Off:
self = .Low
case .Low:
self = .High
case .High :
self = .Off
}
}
}
//MARK: -- 定义类
class Counter {
var count = 0
func increment() {
count += 1 // 类型的每一个实例都有一个隐含属性self,self完全等同于该实例本身,也可以写成 self.count += 1 一般不写self,
}
func incrementBy(amount: Int) {
count += amount
} func reset() {
count = 0
}
}
⦿ 类方法
/*类方法
1. 声明类的类方法,在方法的func关键字之前加上关键字class;
2. 声明结构体和枚举的类方法,在方法的func关键字之前加上关键字static
注意: 在OC中,只能为OC的类定义类方法,在Swift中,可以为类,结构体,枚举定义类方法,每个类方法都被它所支持的类型显式的包含
*/
class SomeClass{
class func someTypeMethod(){
print("调用了类方法")
}
func someInstanceMethods(){
print("调用了实例方法")
}
}
//结构体的类方法
struct LevelTracker {
static var highestUnlockedLevel = 1//静态属性
//定义结构体的类方法 static
static func unlockLevel(level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func levelIsUnlocked(level: Int) -> Bool {
return level <= highestUnlockedLevel
}
var currentLevel = 1//实例属性
//实例方法
mutating func advanceToLevel(level: Int) -> Bool {
if LevelTracker.levelIsUnlocked(level: level) {
currentLevel = level
return true
} else {
return false
}
}
}
class Player {
var tracker = LevelTracker()
let playerName: String
func completedLevel(level: Int) {
LevelTracker.unlockLevel(level: level + 1)
let advance = tracker.advanceToLevel(level: level + 1)
print("\(advance)")
}
init(name: String) {
playerName = name
}
}