通过在 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类的初始化器有三个不同的步骤:
- 设定子类声明的属性的值;
- 调用父类的初始化器;
- 改变父类定义的属性中的值,以及其他任何使用方法,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 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)