Swift学习笔记三-对象和类

作者: Adrift | 来源:发表于2016-04-20 16:07 被阅读189次

    Swift有很多高级特性,个人感觉Swift在语法跟数据结构上比Java要高级好多.

    声明类
    import Foundation
    //使用class和类名创建一个类.类中属性的声明和常量,变量声明一样,唯一的区别就是它们的上下文是类.同样,方法同函数声明也一样.
    class Shape {
        var numberOfSides = 0
        let maxNumber = 0
        func simpleDescripe() -> String {
            return "A shape with \(numberOfSides) sides"
        }
        func calMaxNumber(number:Int) -> String {
            return "The max number is \(number)"
        }
    }
    
    实例化类并访问属性调用方法
    //要创建一个类的实例,在类名后面加上括号,用点语法访问属性和方法
    var shape = Shape()
    shape.numberOfSides = 7
    var shapeDescription = shape.simpleDescripe()
    
    创建构造器(构造方法)
    //上面的类Shape少了一些重要的东西:一个构造函数来初始化类实例,用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是用来区别实例变量的.当创建实例的时候,像给函数传入参数一样一样给类的构造函数传入函数,每个属性都需要被赋值,不然会报错--无论是通过声明(像numberOfSides)还是通过构造函数(就像name)
    //如果需要在删除对象之前进行清理操作,使用deinit创建一个析构函数
    
    继承父类重写方法
    //子类的定义方法是在他们的类名后面加上父类的名字,用冒号分隔.创建类的时候并不需要一个标准的根类,所以可以忽略父类.
    //子类如果要重写父类的方法,需要用override标记.如果没用标记就重写父类方法编译器会报错.编译器同样会检测override标记的方法是否确实在父类中.
    class Sequare: 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 is \(sideLength)"
        }
    }
    let sequare = Sequare(sideLength: 5.0, name: "xiaoming")
    sequare.area()
    sequare.simpleDescription()
    
    //练习: 创建NamedShape的另一个子类Circle,构造器接收两个参数,一个是半径一个是名称,在子类Circle中实现area()和simpleDescription()方法。
    class Circle:NamedShape {
        var radius:Double
        init(radius: Double, name: String) {
            self.radius = radius
            super.init(name: name)
        }
        
        func area() -> Double {
            return radius * radius * 3.14
        }
        
        override func simpleDescription() -> String {
            return "A circle with radius of length is \(radius)"
        }
    }
    
    属性的setter和getter
    //除了存储简单的属性之外,属性还可以有getter方法和setter方法
    //在swift中使用get/set 主要是用来间接获取/改变其他属性的值。在swift中这类属性被称之为“计算属性” ,不要拿其他面向对象语言跟Swift作对比(尤其是Java,OC,Java中的setter跟getter方法就是操作本属性)
    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
            }
    //        set(value) {
    //            sideLength = value / 3.0
    //        }
        }
    }
    var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
    print(triangle.perimeter)
    triangle.perimeter = 9.9
    print(triangle.sideLength)
    //在perimeter的setter中,新值的名字是newValue.可以在set之后显式设置一个名字.
    //注意:EquilateralTriangle类的构造器执行了三步:
    //1.设置子类声明的属性值
    //2.调用子类构造器
    //3.改变父类定义的属性值.其他的工作比如调用方法,getters和setters也可以在这个阶段完成.
    
    属性监视willSet跟didSet
    //如果不需要计算属性,但是仍然需要在设置一个新值之前或者之后运行代码,使用willSet或者didSet.willSet跟didSet用来监视除初始化之外的属性值的变化.当这个值变化之前做点什么别的事,变化之后做点什么别的事.
    //比如,下面的了确保三角形的变成总是和正方形的变成相同
    class TriangleAndSquare {
        
        var  triangle: EquilateralTriangle {
            willSet {
                sequare.sideLength = newValue.sideLength
            }
    //        willSet(value) {
    //            print("willSet")
    //            sequare.sideLength = value.sideLength
    //        }
        }
        
        var sequare: Sequare {
            willSet {
                triangle.sideLength = newValue.sideLength
            }
        }
        
        init(size: Double, name: String) {
            sequare = Sequare(sideLength: size, name: name)
            triangle = EquilateralTriangle(sideLength: size, name: name)
        }
    }
    var triangleAndSquare = TriangleAndSquare(size: 10, name: "Another test sequare")
    print(triangleAndSquare.sequare.sideLength)
    print(triangleAndSquare.triangle.sideLength)
    triangleAndSquare.sequare = Sequare(sideLength: 50, name: "larger sequare")//只有这句才能调用willSet,初始化不调用
    print(triangleAndSquare.triangle.sideLength)
    
    处理可选值
    //处理变量的可选值时,可以在操作(比如属性,方法,子脚本)之前加?.如果?之前的值是nil,则?后面的内容会被忽略,并且整个表达式返回nil.否则?之后的内容都会被执行.这两种情况下整个表达式也是一个可选值
    let optionalSquare: Sequare? = Sequare(sideLength: 20, name: "optional")
    let sideLength = optionalSquare?.sideLength
    print(sideLength!)
    

    本文原地址:Swift学习笔记三-对象和类

    相关文章

      网友评论

        本文标题:Swift学习笔记三-对象和类

        本文链接:https://www.haomeiwen.com/subject/zbnzlttx.html