11.方法
方法是与某些特定类型相关联的函数。类、结构体、枚举都可以定义实例方法;实例方法为给定类型的实例封装了具体的任务与功能。类、结构体、枚举也可以定义类型方法;类型方法与类型本身相关联。结构体和枚举能够定义方法是 Swift 与 C/Objective-C 的主要区别之一。
1.实例方法
- 实例方法是属于某个特定类、结构体或者枚举类型实例的方法。实例方法提供访问和修改实例属性的方法或提供与实例目的相关的功能,并以此来支撑实例的功能。
- 实例方法要写在它所属的类型的前后大括号之间。实例方法能够隐式访问它所属类型的所有的其他实例方法和属性。实例方法只能被它所属的类的某个特定实例调用。实例方法不能脱离于现存的实例而被调用。
//TODO:示例1 class Counter { var count = 0; func increment() { count += 1; } func incrementBy(amount: Int) { count += amount; //没有用self } //带有局部参数名称和外部参数名称的方法 func incrementBy(num amount: Int, times numberOfTimes: Int) { self.count += amount * numberOfTimes; //用了self } //带有默认外部参数名称的方法 func incrementBy(amount: Int, numberOfTimes:Int) { count += amount * numberOfTimes * numberOfTimes; } func reset() { count = 0; } } let counter = Counter(); // 初始计数值是0 counter.increment(); // 计数值现在是1 counter.incrementBy(3); counter.incrementBy(5); // 计数值现在是6 counter.reset(); // 计数值现在是0 counter.incrementBy(num:2, times: 3); // 计数值现在是6 counter.reset(); counter.incrementBy(2, numberOfTimes: 3); // 计数值现在是18 //TODO:示例1说明 //1.Swift 默认仅给方法的第一个参数名称一个局部参数名称(没有外部参数名称);默认同时给第二个和后续的参数名称局部参数名称和外部参数名称。 //2.如果不想为方法的第二个及后续的参数提供一个外部名称,可以通过使用下划线(_)作为该参数的显式外部名称,这样做将覆盖默认行为。 //3.类型的每一个实例都有一个隐含属性叫做self,self完全等同于该实例本身。可以在一个实例的实例方法中使用这个隐含的self属性来引用当前实例。实际上,只要在一个方法中使用一个已知的属性或者方法名称,如果没有明确地写self,Swift 假定是指当前实例的属性或者方法。 //4.实例方法的某个参数名称与实例的某个属性名称相同的时候。在这种情况下,参数名称享有优先权,并且在引用属性时必须使用一种更严格的方式。这时可以使用self属性来区分参数名称和属性名称。 //TODO:示例2 struct Point { var x = 0.0; var y = 0.0; mutating func moveByX(deltaX: Double, y deltaY: Double) { x += deltaX; y += deltaY; } mutating func moveByPoint(deltaX: Double, y deltaY: Double) { self = Point(x: x + deltaX, y: y + deltaY); } } var somePoint = Point(x: 1.0, y: 1.0); somePoint.moveByX(2.0, y: 3.0); //(3.0 4.0) somePoint.moveByPoint(4.0, y: 5.0); //(7.0 9.0) //TODO:示例2说明 //1.默认情况下,值类型(如结构体和枚举)的属性不能在它的实例方法中被修改。如果要修改,将关键字mutating 放到方法的func关键字之前就可以了。 //2.可变方法能够赋给隐含属性self一个全新的实例。
2.类型方法
- 实例方法是被某个类型的实例调用的方法。也可以定义在类型本身上调用的方法,这种方法就叫做类型方法。在方法的func关键字之前加上关键字static,来指定类型方法。类还可以用关键字class来允许子类重写父类的方法实现。
//等级记录 struct LevelTracker { static var highestUnlockedLevel = 1; //玩家已解锁的最高等级 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) { currentLevel = level; return true; } else { return false; } } } //玩家 class Player { var tracker = LevelTracker(); let playerName: String; func completedLevel(level: Int) //完成等级 { LevelTracker.unlockLevel(level + 1); tracker.advanceToLevel(level + 1); } init(name: String) { playerName = name } } var player = Player(name: "Argyrios"); player.completedLevel(1); player.tracker.advanceToLevel(6); //执行false
无善无恶心之体,
有善有恶意之动,
知善知恶是良知,
为善去恶是格物。