Swift学习——A Swift Tour 对象跟类

Swift学习——A Swift Tour 对象和类

Objects and Classes  对象和类


使用关键字 class 定义一个类,在定义类的属性的时候与常量或者变量的定义相同(继承父类的属性定义不同),方法和函数的定义也相同

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

使用 ()来声明类的实例,使用点 . 语法来获取类的属性和方法

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

创建构造函数 init 初始化实例信息

class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
书中还提醒要注意self的使用,相信用过OC的都知道self.name 和 name的区别吧,当实例声明的时候,每个属性都要赋初值,可以再声明的时候赋初值(类似numberOfSides)或者在构造的时候赋初值(类似name)

使用 deinit 在对象被销毁之前做一些清理操作,同OC中的 dealloc 函数


类的继承

使用冒号 : 进行继承,任何类不需要继承标准根类,如NSObject,可以根据需要包含或者省略一个超类

使用 override 关键字对父类的方法进行重写,如果不写关键字,编译器会报错,编译器还会自动检测写了 关键字但是父类实际上没有的方法

class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    
    func area() ->  Double {
        return sideLength * sideLength
    }
    
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

为属性添加 getter 和 setter 函数

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    
    var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }
    
    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength
在 perimeter 的 set 方法中有一个没有声明的 newValue ,接收的值被自动命名为 newValue ,比如上文中的 9.9

上面的构造器中进行以下三个步骤:

1. 为子类的属性赋值

2. 调用父类的构造器

3. 修改父类中定义的属性的值


使用WillSet 和 DidSet 在 setter 一个 newValue 之前和之后执行

class TriangleAndSquare {
    var triangle: EquilateralTriangle {
    willSet {
        square.sideLength = newValue.sideLength
    }
    }
    var square: Square {
    willSet {
        triangle.sideLength = newValue.sideLength
    }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength
保证了三角形和正方形的边长一样


函数的参数只能在函数的内部使用,但是方法的参数名称除了在内部使用还可以在外部使用(第一个参数除外)

class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, numberOfTimes times: Int) {
        count += amount * times
    }
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)
上面代码中 numberOfTimes是别名,可以在外面使用


?的另外一种用途

如果实例的值为 nil ,那么所有调用这个实例的语句都不会起作用

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength

下一节说枚举和结构