实例方法、类型方法。
方法是与某些特定类型相关联的函数。类、结构体、枚举都可以定义实例方法:实例方法为给定类型的实力封装了具体的任务与功能。类、结构体、枚举也可以定义类型方法:类型方法与类型本身相关联。
结构体和枚举能够定义方法是Swift与OC的主要区别之一。在OC中,类是唯一能定义方法的类型。但在Swift中,不仅能选择是否要定义一个类/结构体/枚举,还能灵活地在你创建的类型(类/结构体/枚举)上定义方法。
实例方法:
实例方法属于某个特定类、结构体或者枚举类型实例的方法。实例方法提供访问和修改实例属性的方法或提供与实例目的相关的功能,并以此来支撑实例的功能。
实例方法要写在它所属的类型的前后大括号之间。实例方法能够隐式访问它所属类型的所有的其它实例方法和属性。实例方法只能被它所属的类的某个特定实例调用。实例方法不能脱离于现存的实例而被调用。
class ca{
var a:Int=10
func getA()->Int{
return a
}
}
和调用属性一样,用点语法(dot syntax)调用实例方法。
self属性:
类型的每一个实例都有一个隐含属性叫做self,self完全等同于该实例本身。可以在一个实例的方法中使用这个隐含的self属性来引用当前实例。
实际上,不必在代码里经常写self。不论何时,只要在一个方法中使用一个已知的属性或者方法名称,如果没有明确地写self,Swift假定是指当前实例的属性或者方法。
使用self的主要场景是实例方法的某个参数名称与实例的某个属性名称相同的时候。这种情况下,参数名称享有优先权,并且在引用属性时必须使用self点语法。
在实例方法中修改值类型:
结构体和枚举是指类型。默认情况下,值类型的属性不能在它的实例方法中被修改。
但是,如果确实需要在某个特定的方法中修改结构体或者枚举的属性,可以为这个方法选择 可变(mutating)行为,然后就可以从其方法内部改变它的属性;并且这个方法做的任何改变都会在方法执行结束时写回到原始结构中。方法还可以给它隐含的self属性赋予一个全新的实例,这个新实例在方法结束时会替换现存实例。
要使用可变方法,将关键字mutating
struct Point{
var x=0.0, y=0.0
mutating func moveByX(deltaX:Double, y deltaY: Double){
x+=deltaX
y+=deltaY
}
}
不能在结构体类型的常量上调用可变方法,因为其属性不能被改变,即使属性是变量属性。
let m:Point=Point(x:1.0,y:1.0)
//m不能调用moveByX方法
在可变方法中给self赋值:
struct Point{
var x=0.0, y=0.0
mutating func moveBy(x deltaX:Double, y deltaY:Double){
self=Point(x:x+deltaX,y:y+deltaY)
}
}
枚举的可变方法可以把self设置为同一枚举类型中不同的成员。
enum State{
case Off,Low,High
mutating func next(){
switch self{
case .Off:
self = .Low
case .Low:
self = .High
case .High
self = .Off
}
}
类型方法:
实例方法是被某个类型的实例调用的方法。可以定义在类型本身上调用的方法,这种方法就叫做类型方法。
在方法的func关键字之前加上关键字static,来指定类型方法。类还可以用关键字class来允许子类重写父类的方法实现。
类型方法和实例方法一样用点语法调用。但是,类型方法是在类型上调用这个方法,而非实例。
class SomeClass{
class func someTypeMethod(){
//实现类型方法
}
}
SomeClass.someTypeMethod()
类型方法类型C++中的静态方法。
Swift的类型变量/常量使用static,而类型方法使用static或class。
在类型方法的方法体中,self指向这个类型本身,而不是类型的某个实例。这意味着可以用self消除类型属性和类型方法参数之间的歧义。(类型方法的参数名称可能和类型属性同名)
一个类型方法可以直接通过类型方法的名称调用本类中的其它类型方法,而无需在方法名称前加上类型名称。类似地,在结构体和枚举中,也能够直接通过类型属性的名称访问本类中的类型属性,而不需要前面加上类型名称。