Swift学习笔记之--类和对象

通过在 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()

这个 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来区分 name属性还是初始化器里的 name参数。创建类实例的时候给初始化器传参就好像是调用方法一样。每一个属性都需要赋值——要么在声明的时候(比如说 numberOfSides),要么就要在初始化器里赋值(比如说 name)。

 

使用 deinit来创建一个反初始化器,如果你需要在释放对象之前执行一些清理工作的话。

声明子类就在它名字后面跟上父类的名字,用冒号分隔。创建类不需要从什么标准根类来继承,所以你可以按需包含或者去掉父类声明。

子类的方法如果要重写父类的实现,则需要使用 override——不使用 override关键字来标记则会导致编译器报错。编译器同样也会检测使用 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 triangle with sides of length \(sideLength)."
    }
}
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. 改变父类定义的属性中的值,以及其他任何使用方法,getter 或者 setter 等需要在这时候完成的内容。

 

如果你不需要计算属性但仍然需要在设置一个新值的前后执行代码,使用 willSet和 didSet。比如说,下面的类确保三角形的边长始终和正方形的边长相同。

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")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)

当你操作可选项的值的时候,你可以在可选项前边使用 ?比如方法,属性和下标脚本。如果 ?前的值是 nil,那 ?后的所有内容都会被忽略并且整个表达式的值都是 nil。否则,可选项的值将被展开,然后 ?后边的代码根据展开的值执行。在这两种情况当中,表达式的值是一个可选的值。

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

 

1,init():类的初始化方法

/********************************
使用默认构造函数
********************************/
class Student{
    //类属性
    var name:String = ""
    var number:Int = 0
}
var student = Student()
 
/********************************
自定义构造函数
********************************/
class Person{
    //类属性
    var name:String
    var age:Int
 
    //类构造函数
    init(newName:String, newAge:Int){
        self.name = newName
        self.age = newAge
    }
 
    //类方法
    func say() -> String{
        return "我叫\(name)"
    }
}
var p = Person(newName: "hangge",newAge: 32)
print(p.say())

2,deinit():类反初始化方法(析构方法)

 

class DBClass{
    var conn:Connection? = Connection()
    deinit{
        //可以做一些清理工作
        self.conn!.close()
        self.conn = nil
    }
}
 
var db:DBClass? = DBClass()
db = nil //设置nil后即可执行deinit()方法

 

计算属性:

(1)什么是计算属性

跟存储属性不一样的是,计算属性不是直接存储值,而是提供get和set

get:用来取值,封装取值的过程

set:用来设值,封装设值的过程

代码示例;

class Square {
    // 正方形的宽度
      var width: Double = 0.0
    // 正方形的周长
      var girth: Double {
        get {
            // 周长 = 宽度 * 4
                return width * 4
        }
        set(newGirth) {
            // 宽度 = 周长 / 4
                   width = newGirth / 4
        }
    }
}

计算属性举例:

1 var s = Square()
2 s.width = 10
3 println(s.girth)
4 s.girth = 200 
5 println(s.width) 

 

 

 

posted @ 2016-07-12 11:51  稻草人11223  阅读(240)  评论(0编辑  收藏  举报
返回顶部