详解Swift编程中的方法与属性的概念

方法
在 Swift 中特定类型的相关联功能被称为方法。在 Objective C 中类是用来定义方法,其中作为 Swift 语言为用户提供了灵活性,类,结构和枚举中可以定义使用方法。

实例方法
在 Swift 语言,类,结构和枚举实例通过实例方法访问。

  • 实例方法提供的功能
  • 访问和修改实例属性
  • 函数关联实例的需要

实例方法可以写在花括号 {} 内。它隐含的访问方法和类实例的属性。当该类型指定具体实例它调用获得访问该特定实例。

语法


func funcname(Parameters)-> returntype

{Statement1Statement2---Statement N

    return parameters

}


示例

class calculations {let a:Intlet b:Intlet res:Int

    

    init(a:Int, b:Int){self.a = a

        self.b = b

        res = a + b

    }

    

    func tot(c:Int)->Int{return res - c

    }

    

    func result(){

        println("Result is: \(tot(20))")

        println("Result is: \(tot(50))")}}let pri = calculations(a:600, b:300)

pri.result()


当我们使用 playground 运行上面的程序,得到以下结果

Result is: 880
Result is: 850

Calculations 类定义了两个实例方法:

init() 被定义为两个数 a 和 b 相加,并将其结果存储在'res'

tot() 用于通过从 “res” 值减去 'c'

最后,调用打印的计算a和b的值方法. 实例方法以 "." 语法访问

局部和外部参数名称
Swift 函数描述了局部和全局变量声明。同样,Swift 方法的命名规则也类似 Objective C。但是局部和全局参数名称声明的特性对于函数和方法不同。 swift 第一个参数是由介词名称'with', 'for' 和 'by' 访问命名规则。

Swift 提供声明作为局数参数名称,其它参数名称为全局参数名,第一参数是方法名称。在这里,“no1”方法作为局部参数名来声明。 'no2' 用于全局声明,并通过该程序访问。


class division {var count:Int=0

    func incrementBy(no1:Int, no2:Int){

        count = no1 / no2

        println(count)}}let counter = division()

counter.incrementBy(1800, no2:3)

counter.incrementBy(1600, no2:5)

counter.incrementBy(11000, no2:3)


当我们使用 playground 运行上面的程序,得到以下结果

600
320
3666

外部参数名称使用 # 和 _ 符号
尽管 Swift 方法提供第一个参数名称作为局部声明,用户必须提供以修改参数名称从局部到全局声明。这可以通过'#'符号前缀使用第一参数名来完成。通过这样做,第一参数可以作为全局在整个模块访问。

当用户需要使用外部名称访问在后面的参数名中,方法的名字使用“_”符号覆盖。


class multiplication {var count:Int=0

    func incrementBy(#no1:Int, no2:Int){

        count = no1 * no2

        println(count)}}let counter = multiplication()

counter.incrementBy(no1:800, no2:3)

counter.incrementBy(no1:100, no2:5)

counter.incrementBy(no1:15000, no2:3)


当我们使用 playground 运行上面的程序,得到以下结果

2400
500
45000

在方法中的Self属性
方法有一个隐式属性被称为“self”,所有定义的类型实例所都有。“self”属性被用于表示当前的实例定义的方法。


class calculations {let a:Intlet b:Intlet res:Int

    

    init(a:Int, b:Int){self.a = a

        self.b = b

        res = a + b

        println("Inside Self Block: \(res)")}

    

    func tot(c:Int)->Int{return res - c

    }

    

    func result(){

        println("Result is: \(tot(20))")

        println("Result is: \(tot(50))")}}let pri = calculations(a:600, b:300)let sum = calculations(a:1200, b:300)

pri.result() sum.result()


当我们使用 playground 运行上面的程序,得到以下结果

Inside Self Block: 900
Inside Self Block: 1500
Result is: 880
Result is: 850
Result is: 1480
Result is: 1450

修改的实例方法值类型
在 Swift 语言结构和枚举和值类型不能由它的实例方法来改变。然而,swift 语言通过“变异”行为提供了灵活修改值类型。突变将使得在实例方法中的任何变化,将方法执行之后变化返回到原来的形式。此外,由 “selft” 属性的新实例其隐式函数创建,执行之后将取代现有的方法


struct area {var length =1var breadth =1

    

    func area()->Int{return length * breadth

    }

    

    mutating func scaleBy(res:Int){

        length *= res

        breadth *= res

        

        println(length)

        println(breadth)}}var val = area(length:3, breadth:5)

val.scaleBy(3)

val.scaleBy(30)

val.scaleBy(300)


当我们使用 playground 运行上面的程序,得到以下结果

9
15
270
450
81000
135000

Self 属性的不同诱变方法
突变方法结合 “self” 属性分配给新实例所定义的方法。


struct area {var length =1var breadth =1

    

    func area()->Int{return length * breadth

    }

    

    mutating func scaleBy(res:Int){self.length *= res

        self.breadth *= res

        println(length)

        println(breadth)}}var val = area(length:3, breadth:5)

val.scaleBy(13)


当我们使用 playground 运行上面的程序,得到以下结果

39
65

类型方法
当方法的特定实例调用,它调用一个实例方法并且当方法调用特定类型的方法的一个被定义为 "类型方法“。类型方法 “类” 是由“func”关键字和结构定义,和枚举型方法使用 “func” 关键字之前的“static”关键字定义。

类型方法调用,是通过访问 '.' 而不是调用特定实例的方法,例子和语法如下:


 classMath{class func abs(number:Int)->Int{if number <0{return(-number)}else{return number

        }}}struct absno

{static func abs(number:Int)->Int{if number <0{return(-number)}else{return number

        }}}letno=Math.abs(-35)let num = absno.abs(-5)

println(no) println(num)


当我们使用 playground 运行上面的程序,得到以下结果

35
5

属性
Swift 语言提供了类,枚举或结构相关联值的属性。属性可以被进一步分为存储属性和计算属性。

存储性能和计算属性的区别

这两种存储和计算属性与实例类型相关联。当属性与它的类型值相关联,那么它定义为“类型属性”。存储和计算的属性通常与一个特定类型的实例相关联。然而,属性也可以与类型本身相关联。这样的属性是已知的类型的属性。 属性观察者也被使用

观察存储的属性值

观察子类从父继承而得的属性

存储属性
Swift 介绍存储的属性概念用来存储常量和变量的实例。常量存储的属性由 'let' 关键字定义和存储变量的属性由 “var” 关键字定义。

在定义存储的属性提供了“默认值”

在初始化期间用户可以初始化和修改初始值


structNumber{var digits:Intlet pi =3.1415}var n =Number(digits:12345)

n.digits =67

println("\(n.digits)") println("\(n.pi)")


当我们使用 playground 运行上面的程序,得到以下结果

67
3.1415

考虑在上面的代码,如下面的一行:


let pi = 3.1415


这里,可变圆周率被初始化为存储属性值使用所述实例 pi = 3.1415. 所以,每当实例被称为将持有单独的值是:3.1415。

另一种方法,已存储的属性可能常量结构。这样结构的整个实例将被认为是“常量属性的存储”。


structNumber{var digits:Intlet numbers =3.1415}var n =Number(digits:12345)

n.digits =67

println("\(n.digits)") println("\(n.numbers)") n.numbers =8.7


当我们使用 playground 运行上面的程序,得到以下结果

error: cannot assign to 'numbers' in 'n'
n.numbers = 8.7

重新初始化'数字'为8.7,它将返回指示“数字''被声明为常数的错误消息。

懒存储属性
Swift 提供了所谓的“懒存储属性',当变量被首次初始化它不会计算初始值. “lazy” 修饰符的变量声明之前,把它作为一个懒存储属性。

延迟属性被使用:

要延迟对象的创建。

当属性是依赖于一个类的其他部分,即:尚未知道


class sample {

   lazy varno= number()// `var` declaration is required.}class number {var name ="Swift"}var firstsample = sample()

println(firstsample.no.name)


当我们使用 playground 运行上面的程序,我们得到以下结果
Swift
实例变量
在Objective C 中,存储属性还必须有实例变量用于备份目的,存放在存储的属性声明的值。

Swift 集成了这些概念成一个“存储的属性”声明。而不必有一个相应的实例变量和备份值'存储属性“,包含通过变量名一个位置定义的有关变量属性所有信息集成,数据类型和存储器管理功能。

计算属性
而不是存储计算的属性值提供了一个getter和一个可选的 setter 间接来检索和设置其他属性和值。


class sample {var no1 =0.0, no2 =0.0var length =300.0, breadth =150.0var middle:(Double,Double){get{return(length /2, breadth /2)}set(axis){

         no1 = axis.0-(length /2)

         no2 = axis.1-(breadth /2)}}}var result = sample()

println(result.middle)

result.middle =(0.0,10.0)

println(result.no1)               println(result.no2)


当我们使用 playground 运行上面的程序,我们得到以下结果

(150.0, 75.0)
-150.0
-65.0

当计算的属性留下了新的值为未定义默认值将针对特定的变量来设置。

计算属性为只读属性
在计算属性只读属性被定义为 getter,但不是 setter。它总是用来返回一个值。变量通过使用 '.' 语法访问,但不能被设置为其他值。


class film {var head =""var duration =0.0var metaInfo:[String:String]{return["head":self.head,"duration":"\(self.duration)"]}}var movie = film()

movie.head ="Swift Properties"

movie.duration =3.09

println(movie.metaInfo["head"]!)      println(movie.metaInfo["duration"]!)


当我们使用 playground 运行上面的程序,我们得到以下结果

Swift Properties
3.09

计算属性属性观察者
在Swift 中使用属性观察者来观察和设置属性值响应。 当每一次属性值设置属性观察者都被调用。 除了懒存储属性,我们可以通过添加属性观察者“继承”属性“覆盖”方法。

在存放值之前 - willset

存储新的值之后 - didset

当一个属性被设置在初始化 willset 和 didset 观察者不能调用。


classSamplepgm{var counter:Int=0{

      willSet(newTotal){

         println("Total Counter is: \(newTotal)")}

      didSet{if counter > oldValue {

            println("Newly Added Counter \(counter - oldValue)")}}}}letNewCounter=Samplepgm()NewCounter.counter =100NewCounter.counter =800


当我们使用 playground 运行上面的程序,我们得到以下结果

Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700

局部和全局变量
对于计算和观察属性局部和全局变量的声明。

类型属性
属性定义类型定义部分有大括号{},并且变量的范围也被前面所定义。要定义值类型使用 “static” 关键字以及类的类型使用 “class” 关键字。

语法


structStructname{staticvar storedTypeProperty =" "staticvar computedTypeProperty:Int{// return an Int value here}}enumEnumname{staticvar storedTypeProperty =" "staticvar computedTypeProperty:Int{// return an Int value here}}classClassname{classvar computedTypeProperty:Int{// return an Int value here}}


查询和设置属性
类似于实例属性类型属性查询和设置,只是使用 “.” 语法,而不用指向该实例的类型。

 structStudMarks{staticlet markCount =97staticvar totalCount =0varInternalMarks:Int=0{

      didSet {ifInternalMarks>StudMarks.markCount {InternalMarks=StudMarks.markCount

         }ifInternalMarks>StudMarks.totalCount {StudMarks.totalCount =InternalMarks}}}}var stud1Mark1 =StudMarks()var stud1Mark2 =StudMarks()

stud1Mark1.InternalMarks=98 println(stud1Mark1.InternalMarks)

stud1Mark2.InternalMarks=87 println(stud1Mark2.InternalMarks)


当我们使用 playground 运行上面的程序,我们得到以下结果

97
87