Part 2:(Methods,Subscripts,Inheritance)

来源:互联网 发布:正版linux 编辑:程序博客网 时间:2024/05/18 00:15

11Methods


方法是与某个特定类相关联的函数。

类,结构体,和枚举都既可以定义成员方法,也可以定义类方法,类方法与oc中的概念相似。

相比之下,在oc中只有类可以定义方法。


11.1Instance Methods


成员方法就是那些属于某个实例,结构体,枚举的函数。

下面这个类定义三个成员方法

class Counter {

   var count =0

   func increment() {

       count++

    }

   func incrementBy(amount:Int) {

       count += amount

    }

   func reset() {

       count =0

    }

}


11.1.1Local and External Parameter Names for Methods


Function parameters can have both a local name (for use within the function’s body) and an external name (for use when calling the function)


函数的参数可以有局部名和外部名称


Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both localand external parameter names by default. 


默认情况下,方法的第一个参数只是局部名称,从第二个参数开始,它既是局部名称,也是外部名称


看看这个新版本的Counter

class Counter {

   var count:Int =0

   func incrementBy(amount:Int, numberOfTimes: Int) {

       count += amount * numberOfTimes

    }

}


let counter =Counter()

counter.incrementBy(5, numberOfTimes:3)

// counter value is now 15


我们不需要给第一个参数增加外部名称,因为它的意义已用incrementby说明白了,从第二个参数开始才需要外部名称


还记得函数上把#号放在局部名称前,则局部名称也是外部名称吗。

swift的处理就好像从第二个参数开始,默认帮你加上#似的


11.1.2Modifying External Parameter Name Behavior for Methods


如果你确实想给第一个参数增加外部名称,那么你可以自己写一个上去,你可以用加#的方法。

相反,如果你不想从第二个开始有默认的外部名称呢,那么你可以在用“_”下划线作为显示外部名称。


11.1.3The self Property


每个实例都有一个隐式的属性self指向实例本身

在实际应用中,我们一般不需要写self,除非这个方法中得参数名与实例的属性名相同,这时需要用self来消除歧义


11.1.4Modifying Value Types from Within Instance Methods


结构体和枚举是值类型,默认的,不能在成员方法中修改值类型的属性

如果要修改则需要在方法前面加mutating关键字,这种修改甚至可以修改self属性,即修改整个实例

当然,如果这个实例是let常量,那么也不能调用mutating方法修改其属性值


struct Point {

   var x =0.0, y =0.0

   mutatingfunc moveByX(deltaX:Double, y deltaY:Double) {

       x += deltaX

       y += deltaY

    }

}

var somePoint =Point(x:1.0, y:1.0)

somePoint.moveByX(2.0, y:3.0)

println("The point is now at (\(somePoint.x),\(somePoint.y))")

// prints "The point is now at (3.0, 4.0)"


let fixedPoint =Point(x:3.0, y:3.0)

fixedPoint.moveByX(2.0, y:3.0)

// this will report an error



11.1.5Assigning to self Within a Mutating Method


mutating方法内修改结构体,枚举的self属性

struct Point {

   var x =0.0, y =0.0

   mutatingfunc moveByX(deltaX:Double, y deltaY:Double) {

       self =Point(x:x + deltaX, y:y + deltaY)

    }

}


enum TriStateSwitch {

   case Off, Low, High

   mutatingfunc next() {

       switchself {

       case Off:

           self =Low

       case Low:

           self =High

       case High:

           self =Off

        }

    }

}

var ovenLight =TriStateSwitch.Low

ovenLight.next()

// ovenLight is now equal to .High

ovenLight.next()

// ovenLight is now equal to .Off



11.2Type Methods


类方法

classes的类方法是在func前面加class关键字

structure和enumeration的类方法是在func前面加static关键字


类方法用类名和点来访问,不能通过实例和点来访问

类方法中得self指的是类,不是实例

类方法中可以调用和访问另一个类方法或属性,调用时可以省略self


12Subscripts


类,结构体,枚举都可以定义下标来访问集合,列表,序列的元素


12.1Subscript Syntax


其语法类似成员方法和计算属性的语法,使用subscript关键字


subscript(index:Int) ->Int {

   get {

        // return an appropriate subscript value here

    }

    set(newValue) { //newValue可以省略,默认的就是newValue

        // perform a suitable setting action here

    }

}


12.2Subscript Usage


var numberOfLegs = ["spider":8,"ant": 6, "cat": 4]

numberOfLegs["bird"] =2


这是Dictionary的一个例子,至于下标的实际意义由类来定。


12.3Subscript Options


下标可以有任意多个入参,入参可以是任意类型。下标可以返回任意类型。

可以使用变量参数和不定个数参数,但不能使用in-out参数,也不能有默认值


类和结构体可以有任意多个下标方法

定义多个下标方法,即下标重载


13Inheritance


类可以继承方法,属性和其他特性

继承下来的新类叫subclass,被继承的类叫superclass


类可以给继承下来的属性增加观察者,不管是存数属性还是计算属性都可以


13.1Defining a Base Class


Any class that does not inherit from another class is known as a base class.


一个不继承于其他类的类成为基类


NOTE

Swift classes do not inherit from a universal base class. Classes you define without specifying a superclass automatically become base classes for you to build upon.


swift类没有默认的父类,没有指定父类的类自动就是基类


下面定义一个基类

class Vehicle {

   var currentSpeed =0.0

   var description:String {

        return"traveling at\(currentSpeed) miles per hour"

    }

   func makeNoise() {

        // do nothing - an arbitrary vehicle doesn't necessarily make a noise

    }

}


let someVehicle =Vehicle()


println("Vehicle:\(someVehicle.description)")

// Vehicle: traveling at 0.0 miles per hour


13.2Subclassing


class Bicycle:Vehicle {

   var hasBasket =false

}


class Tandem:Bicycle {

   var currentNumberOfPassengers =0

}


13.3Overriding


子类可以覆盖实例方法,类方法,实例属性,类属性,下标方法。


写下“override”已明确表示你要覆盖父类的方法,以便编译器进行检查


13.3.1Accessing Superclass Methods, Properties, and Subscripts


覆盖后,如何访问父类的方法,属性,下标

super.someMethod()  //方法

super.someProperty  //属性

super[someIndex] //下标



13.3.2Overriding Methods


class Train:Vehicle {

   overridefunc makeNoise() {

        println("Choo Choo")

    }

}

let train =Train()

train.makeNoise()

// prints "Choo Choo"


13.3.3Overriding Properties


重写实例的属性和类属性,可在里面增加观察者


13.3.3.1Overriding Property Getters and Setters


可重写属性的getset方法,不管是存储属性还是计算属性。

实际上,子类并不知道父类的这个属性到底是存储属性还是计算属性。

它只知道有这个类型的这个名称的属性。


You can present an inherited read-only property as a read-write property by providing both a getter and a setter in your subclass property override. You cannot, however, present an inherited read-write property as a read-only property.

如果父类的这个属性是只读属性,你可重写成可读可写属性,

但如果父类的这个属性是可读可写的,你不能重写成只读的。



class Car:Vehicle {

   var gear =1

   overridevar description:String {

       returnsuper.description +" in gear\(gear)"

    }

}


let car =Car()

car.currentSpeed =25.0

car.gear = 3

println("Car:\(car.description)")

// Car: traveling at 25.0 miles per hour in gear 3


13.3.3.2Overriding Property Observers


注意1

没法给常量存储属性和只读计算属性增加观察者,因为他们的值根本就不能改变,所以不应该有观察值(willSet, didSet)


注意2

同一个属性不应该既有setter又有willSetdidSet,因为willSet和didSet的内容可以在Setter里面实现。


class AutomaticCar:Car {

   overridevar currentSpeed:Double {

       didSet {

           gear =Int(currentSpeed /10.0) +1

        }

    }

}


let automatic =AutomaticCar()

automatic.currentSpeed =35.0

println("AutomaticCar:\(automatic.description)")

// AutomaticCar: traveling at 35.0 miles per hour in gear 4


我英语不好,这是值自动挡汽车么,当速度变化时,自动变档。。。


13.4Preventing Overrides


如果你的方法,属性,下标不想被重写,怎么办呢?在前面加final (final var, final func, final class func, final subscript)


如果类不想被继承,可以 final class

0 0