13.Swift方法
2018-07-04 本文已影响0人
biyu6
/**方法:是与某些特定类型相关联的函数。
实例方法:为给定类型的实例封装了具体的任务与功能。类、结构体、枚举都可以定义实例方法
类型方法:与类型本身相关联,类似于OC的类方法。类、结构体、枚举也可以定义类型方法
OC中类是唯一能定义方法的类型,但在Swift中,结构体和枚举页可以灵活的在创建的类型(类、结构体、枚举)上定义方法
*/
//=======================实例方法(Instance Methods)=======================
/**实例方法:提供访问和修改实例属性的方法 或 提供与实例目的相关的功能,并以此来支撑实例的功能。
实例方法的语法与函数完全一致,写在s它所属的类型的前后大括号之间。
实例方法能够隐式访问它所属类型的所有的其他实例方法和属性
实例方法只能被它所属的类的某个特定实例调用。
实例方法不能脱离于现存的实例而被调用。
*/
class Counter {
var count = 0
func increment(){//按1递增 的实例方法
count += 1
}
func increment(by amount:Int) {//按一个指定的整数值递增 的实例方法
count += amount
}
func reset() {//将计数器重置为0
count = 0
}
}
//调用:
let counter = Counter()//0
print("计数器的值为:\(counter.count)")
counter.increment()//1
print("计数器的值为:\(counter.count)")
counter.increment(by: 5)//6
print("计数器的值为:\(counter.count)")
counter.reset()//0
print("计数器的值为:\(counter.count)")
//self属性: 类型的每一个实例都有一个隐含属性叫做self,self等同于该实例本身,可以在一个实例的实例方法中使用这个隐含的self属性来引用当前实例
struct Point {//特殊情况,结构体属性名与其内的函数参数名相同,在结构体的属性名前加self.来区分
var x = 0.0, y = 0.0
func isToTheRightOfX(x: Double) -> Bool {//函数传入一个名为x的参数,返回一个布尔值
return self.x > x //self.x指的是该结构体的属性x;x指的是该函数的参数且享有优先权
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOfX(x: 1.0) {
print("这个点在x==1.0的右边")
}
//在实例方法中修改值类型
//结构体和枚举是值类型,默认情况下,值类型的属性不能在它的实例方法中被修改。但可以为这个方法选择可变行为,然后从方法内部改变它的属性
struct Point2 {
var x = 0.0, y = 0.0
mutating func moveByX(deltaX: Double, y deltaY: Double){//在func前加入关键字mutating使其成为可变方法,从而允许修改属性,该方法被调用时修改了Point2实例的属性x,y;而不是返回一个新的点。
x += deltaX
y += deltaY
//可变方法做的任何改变都会在方法执行结束时写回到原始结构中,方法还可以给她隐含的self属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。
}
}
var somePoint2 = Point2(x: 3.0, y: 3.0)
somePoint2.moveByX(deltaX: 2.0, y: 4.0)
print("新的点的值为:\(somePoint2.x),\(somePoint2.y)")
//注意,不能爱结构体类型的常量上调用可变方法,因为其属性不能被改版,即使属性是变量属性;以下代码会报错
//let fixedPoint = Point2(x: 3.0, y: 3.0)
//fixedPoint.moveByX(deltaX: 2.0, y: 2.0)
//在可变方法中给self赋值
struct Point3 {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {//该方法创建了一个新的结构体实例,它的x、y值都被设定为目标值
self = Point3(x: x + deltaX, y: y + deltaY)//可变方法能够赋给隐含属性self一个全新的实例
}
}
var somePoint3 = Point3(x: 1.0, y: 1.0)
somePoint3.moveBy(x: 2.0, y: 2.0)
print("新的点的值为:\(somePoint3.x),\(somePoint3.y)")
//枚举的可变方法
enum TriStateSwitch {//三种状态的开关
case Off,Low,High
mutating func next() {//可变方法可以把self设置为同一枚举类型中不同的成员,每次调用该方法时,开关在不同的电源状态直接循环切换
switch self {
case .Off:
self = .Low
case .Low:
self = .High
case .High:
self = .Off
}
}
}
var ovenLight = TriStateSwitch.Low
ovenLight.next()//.High
ovenLight.next()//.Off
//=======================类型方法(Type-level Methods)=======================
//类型方法:是定义在类型本身上调用的方法,类似于OC的类方法。
//定义:在方法的func前面加上关键字static,来指定类型方法。类还可以用关键字class来允许子类重写父类的方法实现。
//类、结构体、枚举也可以定义类型方法,每一个类型方法都被它所支持的类型显式包含。
class SomeClass {
class func someTypeMethod() {
}
}
SomeClass.someTypeMethod()//调用类型方法
//在类型方法的主体中,self指向这个类型本身,而不是类型的某个实例。
struct LevelTracker {//监测玩家已解锁的最高等级
static var highestUnlockedLevel = 1 //玩家的最高等级
var currentLevel = 1 //记录每个玩家当前的游戏等级
static func unlock(_ level: Int){//一旦新等级被解锁,就更新highestUnlockedLevel的值
if level > highestUnlockedLevel {
highestUnlockedLevel = level
}
}
static func isUnlocked(_ level: Int) -> Bool {//若传入的等级已解锁,将返回true
return level <= highestUnlockedLevel
}
@discardableResult //允许调用下方函数时忽略返回值,加上这句不会产生编译警告
mutating func advance(to level: Int) -> Bool {//记录传入的等级是否已经解锁,返回是否能够设置当前等级
if LevelTracker.isUnlocked(level) {//如果没有升级,记录当前的等级
currentLevel = level
return true
}else{
return false
}
}
}
class Player{//监测和更新每个玩家的发展进度
var tracker = LevelTracker()
let playerName: String
func complete(level: Int){//完成了第lever关
LevelTracker.unlock(level + 1)//解锁第lever+1关
tracker.advance(to: level + 1)//记录当前玩家进行的是第几关
}
init(name: String) {
playerName = name
}
}
//调用测试
var player = Player(name: "玩家一")
player.complete(level: 1)//完成了第一关
print("已解锁的关卡是:\(LevelTracker.highestUnlockedLevel)")
player = Player(name: "玩家二")
if player.tracker.advance(to: 6) {
print("第6关已经解锁")
}else{
print("第6关没有解锁")
}