博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift学习3---类和对象
阅读量:5313 次
发布时间:2019-06-14

本文共 4049 字,大约阅读时间需要 13 分钟。

在Swift中,类的初始化要经过两个阶段

(1)第一个阶段,每一个存储属性都被设置了一个初始值。

(2)在第二个阶段,每个类在这个实例被使用之前都会有机会来设置它们相应的存储属性

1.创建和使用类

  使用 class 和类名来创建一个类。类中属性的声明和常量、变量声明一样,唯一的区别就是 它们的上下文是类。同样,方法和函数声明也一样。 

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

  创建Shape类的实例,并调用其字段和方法。

var shape = Shape()shape.numberOfSides = 7var 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."    }}

注意:通过init构建对象,既可以使用self显式引用成员字段(name),也可以隐式引用(numberOfSides)。

   如果你需要在删除对象之前进行一些清理工作,使用 deinit 创建一个析构函数进行清理。 

2.继承和多态

  子类的定义方法是在它们的类名后面加上父类的名字,用冒号分割。创建类的时候并不需要 一个标准的根类,所以你可以忽略父类。 

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()

  为了简化代码,Swift引入了属性(property),见下面的perimeter字段:

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.perimetertriangle.perimeter = 9.9triangle.sideLength

注意:赋值器(setter)中,接收的值被自动命名为newValue你可以在 set 之后显示的设置一个名 字。 

3.willSet和didSet

  注意 EquilateralTriangle 类的构造器执行了三步:

  1. 设置子类声明的属性值
  2. 调用父类的构造器
  3. 改变父类定义的属性值。其他的工作比如调用方法、getters 和 setters 也可以在这个阶 段完成。

  如果你不需要计算属性但是需要在设置一个新值之前运行一些代码,使用 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")triangleAndSquare.square.sideLengthtriangleAndSquare.square = Square(sideLength: 50, name: "larger square")triangleAndSquare.triangle.sideLengt

比如,上面的类确保三角形的边长总是和正方形的边长相同 

4.调用方法

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

class Counter {    var count: Int = 0    func incrementBy(amount: Int, numberOfTimes times: Int) {        count += amount * times    }}var counter = Counter()counter.incrementBy(2, numberOfTimes: 7) //注意Swift支持为方法参数取别名:在上面的代码里,numberOfTimes面向外部,times面向内部。

5.?的另一种用途

  使用可空值时,?可以出现在方法、属性或下标前面。如果?前的值为nil,那么?后面的表达式会被忽略,而原表达式直接返回nil,例如:

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")let sideLength = optionalSquare?.sideLength //当optionalSquare为nil时,sideLength属性调用会被忽略。

6.补充

初始化

  init关键词,和OC一样。不过这块非常像CPP,如下面这东西

class nyan{         var num: Int = 1024         init()         {             num = 1;         }     }           class miao:nyan     {         var num1: Int = 1

      override init() { 

num1 = 2         }     } var a = miao()       println(a.num) println(a.num1) //如果以OC的思维来看,它输出的应该是 1024, 2。因为OC只要没有call super,就是覆盖掉了。 //但实际上Swift输出的是 1, 2。倘若,我们在两个init加上打log的话,会发现,子类的init先运行,然后运行父类的。那么什么时候在子类的init里面call super.init()呢? 显而易见:当在子类里面要调用父类的成员变量时,要先调用super.init()去初始化它,若没有写的话,XCode会报编译错误。

 

 

转载于:https://www.cnblogs.com/ShawnLi/p/4502116.html

你可能感兴趣的文章
Python中替换元素
查看>>
关于双核心:也许你不知道的五件事
查看>>
Trace 2018徐州icpc网络赛 (二分)(树状数组)
查看>>
让你的 Python 代码优雅又地道
查看>>
Centos7.2正常启动关闭CDH5.16.1
查看>>
Android 监听返回键、HOME键
查看>>
Android ContentProvider的实现
查看>>
jmeter里面Dug Sampler 和json提取器的用法
查看>>
sqlserver 各种判断是否存在(表名、函数、存储过程等)
查看>>
公司居然使用监听设备,大家来讨论下IT公司应该怎样管理
查看>>
一句简单的SQL----模糊 查询
查看>>
编程十年 (13):毁人不倦1
查看>>
排序算法小结
查看>>
Android Core
查看>>
给C#学习者的建议 - CLR Via C# 读后感
查看>>
Recover Binary Search Tree
查看>>
Java 实践:生产者与消费者
查看>>
[转]IOCP--Socket IO模型终结篇
查看>>
SpringBoot实战 之 异常处理篇
查看>>
【转】【OPenGL】opengl 64位 配置 freeglutx64下载
查看>>