Swift基础语法: 28 - Swift的实例方法, Self属性, 类型方法

前端之家收集整理的这篇文章主要介绍了Swift基础语法: 28 - Swift的实例方法, Self属性, 类型方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在Swift中,我们也有相应的实例方法,Self属性,还有类型方法,其实这些都是和OC中的方法类似的,只是语法上有些不同,下面让我们一起来看看吧:


1.实例方法

实例方法是属于某个特定类、结构体或者枚举类型实例的方法,是用来访问,修改实例属性,也提供相应的与实例相关的功能,下面让我们一起来看看例子:

class@H_404_11@ Counter@H_404_11@ {@H_404_11@
    var count@H_404_11@ = 0@H_404_11@
    func increment() {
        count@H_404_11@++
    }
    func incrementBy(amount: Int) {
        count@H_404_11@ += amount
    }
    func reset() {
        count@H_404_11@ = 0@H_404_11@
    }
}

let counter = Counter()
println(counter.count@H_404_11@)
// 打印出来的结果: 0@H_404_11@

counter.increment()
println(counter.count@H_404_11@)
// 打印出来的结果: 1@H_404_11@

counter.incrementBy(5@H_404_11@)
println(counter.count@H_404_11@)
// 打印出来的结果: 6@H_404_11@

counter.reset()
println(counter.count@H_404_11@)
// 打印出来的结果: 0@H_404_11@

PS: 在方法中,除了有内部参数之外,其实还可以导入外部参数,当然,方法参数也是如此,但方法函数的局部名称和外部名称的默认行为是不一样的,比如:

class@H_404_11@ Counter@H_404_11@ { var count: Int@H_404_11@ = 0 func incrementBy(amount@H_404_11@: Int@H_404_11@,numberOfTimes@H_404_11@: Int@H_404_11@)@H_404_11@ { count += amount * numberOfTimes } } let counter = Counter@H_404_11@()@H_404_11@ counter.incrementBy(5,numberOfTimes@H_404_11@: 3)@H_404_11@ println(counter@H_404_11@.count@H_404_11@)@H_404_11@ // 打印出来的结果: 15@H_404_11@

PS: 在这个方法中,它会把amount这个参数当成一个内部参数,而numberOfTimes就当成一个外部参数,如果要去记忆它们的话,那么就想成一个不需要写参数名,一个需要写参数名就OK了.


2.Self属性

类型的每一个实例都有一个隐含属性叫做 self,self 完全等同于该实例本身,你可以在一个实例的实例方法中使用这个隐含的 self 属性来引用当前实例,比如:

func@H_404_11@ increment()@H_404_11@ {@H_404_11@
    self@H_404_11@.@H_404_11@count@H_404_11@+@H_404_11@+@H_404_11@
}@H_404_11@

但在Swift中,我们是不需要经常写Self的,因为只要在一个方法中使用一个已知的 属性或者方法名称,如果你没有明确的写 self,那么Swift就假定你是指当前实例的属性或者方法,让我们来看看例子:

struct Point {
    var@H_404_11@ x=0.0@H_404_11@,y=0.0@H_404_11@
    func isToTheRightOfX(x: Double)@H_404_11@ ->@H_404_11@ Bool {
        return@H_404_11@ self.x > x
    }
}

let@H_404_11@ somePoint = Point(x@H_404_11@: 4.0@H_404_11@,y@H_404_11@: 5.0@H_404_11@)

if@H_404_11@ somePoint.isToTheRightOfX(1.0@H_404_11@) {
    println("This point is to the right of the line where x == 1.0"@H_404_11@)
}
//@H_404_11@ 打印出来的结果: This point is@H_404_11@ to the right of@H_404_11@ the line where x == 1.0@H_404_11@

PS: 如果不使用 self 前缀,Swift 就认为两次使用的 x 都指的是名称为 x 的函数参数。

在我们开发的过程中,我们或许有特殊的需求,需要去修改实例中的一些值类型,但直接修改是不可能会实现的,在Swift中需要用到一些特殊的手段,该方法我们称为变异方法,让我们一起来看看吧:

struct@H_404_11@ Point {
    var@H_404_11@ x = 0.0@H_404_11@,y = 0.0@H_404_11@
    mutating func@H_404_11@ moveByX(deltaX: Double,y deltaY: Double){
        x += deltaX
        y += deltaY
    }
}
var@H_404_11@ somePoint = Point(x: 1.0@H_404_11@,y: 1.0@H_404_11@)
somePoint.moveByX(2.0@H_404_11@,y: 3.0@H_404_11@)
println@H_404_11@("The point is now at (\(somePoint.x),\(somePoint.y))"@H_404_11@)
// 打印出来的结果: This point is to the right of the line where x == 1.0@H_404_11@

PS: 这里要注意一下,mutatinga该关键字只能用在变量里,如果使用在常量里的话,编译器是会报错的,比如:

let@H_404_11@ fixedPoint = Point(x: 3.0@H_404_11@,y: 3.0@H_404_11@)
fixedPoint.moveByX(1.0@H_404_11@,y: 2.0@H_404_11@)
// 报错: Immutable value of type@H_404_11@ 'Point'@H_404_11@ only has mutating members named 'moveByX'@H_404_11@

但是mutating该方法是可以在Self里使用的,比如:

struct@H_404_11@ Point {
    var@H_404_11@ x = 0.0@H_404_11@,y deltaY: Double) {
        self = Point(x: x + deltaX,y: y + deltaY)
    }
}

enum TriStateSwitch {
    case@H_404_11@ Off,Low,High
    mutating func@H_404_11@ next() {
    switch@H_404_11@ self {
        case@H_404_11@ Off:
            self = Low
        case@H_404_11@ Low:
            self = High
        case@H_404_11@ High:
            self = Off
        }
    }
}

var@H_404_11@ ovenLight = TriStateSwitch.Low
println@H_404_11@(ovenLight.hashValue)
// 打印出来的结果: 1@H_404_11@

ovenLight.next()
println@H_404_11@(ovenLight.hashValue)
// 打印出来的结果: 2@H_404_11@

ovenLight.next()
println@H_404_11@(ovenLight.hashValue)
// 打印出来的结果: 0@H_404_11@

3.类型方法

在Swift中也有类型方法,但定义方式不太一样,需要在func关键字之前加一个class,这样子就变成了类方法了,如果要声明结构体或者是枚举方法,那就要在func前面加static这个关键字,和OC不同的是,Swift可以为所有的类,结构体,枚举定义类方法,让我们来看看例子吧:

class@H_404_11@ SomeClass@H_404_11@ {@H_404_11@
class@H_404_11@ func@H_404_11@ someTypeMethod@H_404_11@()@H_404_11@ {@H_404_11@
        println("abc"@H_404_11@)
    }
}
SomeClass.someTypeMethod()
// 打印出来的结果: abc@H_404_11@

PS: 因为SomeClass是类方法,所以我们不需要实例某个对象才调用,我们可以直接去使用.

我们来看一个比较综合一点的例子:

struct LevelTracker {
    static var@H_404_11@ highestUnlockedLevel = 1@H_404_11@
    static func unlockLevel(level@H_404_11@: Int) {
        if@H_404_11@ level > highestUnlockedLevel {
            highestUnlockedLevel = level
        }
    }

    static func levelIsUnlocked(level: Int)@H_404_11@ ->@H_404_11@ Bool {
        return@H_404_11@ level <= highestUnlockedLevel
    }

    var@H_404_11@ currentLevel = 1@H_404_11@
    mutating func advanceToLevel(level: Int)@H_404_11@ ->@H_404_11@ Bool {
        if@H_404_11@ LevelTracker.levelIsUnlocked(level) {
            currentLevel = level
            return@H_404_11@ true@H_404_11@
        } else@H_404_11@ {
            return@H_404_11@ false@H_404_11@
        }
    }
}

PS: 这个例子中,我们是在结构体中定义了静态变量,结构体方法,变异方法.

然后我们需要再定义一个类,用来监听LeveTracker该结构体:

class@H_404_11@ Player {
    var@H_404_11@ tracker = LevelTracker()
    let@H_404_11@ playerName: String@H_404_11@
    func completedLevel(level: Int) {
        LevelTracker.unlockLevel(level + 1@H_404_11@)
        tracker.advanceToLevel(level + 1@H_404_11@)
    }
    init (name: String@H_404_11@) {
        playerName = name
    }
}

var@H_404_11@ player = Player(name: "Argyrios"@H_404_11@)
player.completedLevel(1@H_404_11@)
println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)"@H_404_11@)
// 打印出来的结果: highest unlocked level is now 2@H_404_11@

player = Player(name: "Beto"@H_404_11@)
if@H_404_11@ player.tracker.advanceToLevel(6@H_404_11@) {
        println("player is now on level 6"@H_404_11@)
    } else@H_404_11@ {
        println("level 6 has not yet been unlocked"@H_404_11@)
}
// 打印出来的结果: level 6 has not yet been unlocked@H_404_11@

好了,这次我们就讲到这里,下次我们继续~~~

猜你在找的Swift相关文章