美文网首页
swift —— 对象和类

swift —— 对象和类

作者: RX78178 | 来源:发表于2016-12-20 14:54 被阅读121次

使用 'class' 关键字后跟类名来创建一个类。在一个类中,申明一个属性的写法,同申明一个常量或变量的写法是一样的。同样的,类中的方法(method)同函数(function)的申明写法是一样的。例:


class

通过在类名后添加括号来创建一个类的实例。使用 ‘点语法’ 来调用一个实例的属性和方法。例:


dot syntax

目前这个版本的 ‘Shape’ 类缺少了一些重要的东西 —— 一个构造器,当一个创建一个实例的时候,初始化一个类。使用 ‘init’来创建一个(构造器)


init

可以看到,在swift中,init方法不需要调用父类的init(虽然例子中的类并没有父类)。这一点和oc中是不同的。在后面的篇章中,会对这一问题有更多的讨论。
在这里要留意下,在构造器中‘self’被用来将(NameShape,即本类的)name属性和 name形参区分开。当你创建一个类的实例时,构造器中的参数被一一传递第就像是一个函数调用。每个属性需要分配一个值 —— 要么是在它(属性)申明的时候(像是numberOfSides)要么是在构造器中(像是name)。
使用 ‘deinit’ 创建一个析构器(类似于 dealloc)如果你需要在对象被释放前,做一些清理工作的话。
子类们在他们的类名之后,包含他们的父类名称,使用冒号区分开。对类而言,并不需要基于一个标准的根类(standard root class),所以,你可以按需要包含或者是忽略父类。
子类中的方法,如果重写了父类的实现,那就需要使用 ‘override’ 关键字来标示 —— 如果没有加 ‘override’ 关键字,而意外的覆盖了一个方法,这将会被编译器认为是一个错误。编译器同样也会侦测出那些使用了‘override’关键字——却实际上并没有覆盖任何父类中的方法——的方法。例:


override
从图中的例子中可以看到,在子类的构造方法中,首先初始化self的属性,然后调用super的构造方法。而且,在调用super的init 方法前,是不能调用name属性的。原因是name是从父类继承下来的属性,而在调用super的init的方法前,self并没有初始化,所以也就调用不到name。
在oc中,构造函数是首先调用super的init,这样先构造出self,而后可以对self进行进一步的初始化操作。swift中,首先将self的私有属性赋初始值,而后在构造self(通过调用super的init)。这个流程和oc是不一样的。

实际上,熟悉oc的开发者会知道,oc中的super实际上指的是self。也就是说,在oc中[super init]实际上使用self调用super的init方法。这个过程中,self的所有实际上都会被初始化。而在super的init方法中没有初始化的属性(self的私有属性)就会有一个默认的值。譬如说,bool 类型的话就是no,NSArray类型的话就是nil等等。
swift中,self在调用super的init方法前必须先将自己的私有属性全部赋初始值,不然会报错


error
swift中的super.init初始化的仅仅是super中的属性,和self的私有属性是没有关系的了。这么做其实更严谨。

除了简单的存储属性之外,属性还能有setter和getter方法。例:


setter/getter

oc的类中,每一个属性都会默认有一个setter和getter方法。而在swift中,拥有setter/getter方法的是计算属性,而用来存储值(结果)的存储属性。如例中,sideLength是存储属性,而perimeter是计算属性。此二者是不一样的。
如果,将例子中的perimeter的set方法改为,perimeter = newValue / 3.0。那么结果就会变成死循环。因为此时perimeter是左值,意味着在set方法中不断地在调用set方法,最终导致死循环。(然而在编译中是可以通过的)在后面的篇章中会看到,category中可以添加计算属性,但是不能添加存储属性(继承于NSObject的可以使用runtime,但实际上,这样添加的存储属性,也不是真正意义上的属性)。原因是category是在类的方法列表(method list)中添加方法——扩展方法列表。而类的属性存在于属性列表(property list)中,所以category是不能添加属性的。
类实例管理着属性列表(的地址),属性列表中存储的是类属性的地址,category为方法列表添加方法,也就是在方法列表中添加新方法的地址。

在perimeter的setter方法中,新的值有一个隐式的名称 —— newValue。你可以在set之后,添加括号,然后给出一个显式的名称,例如:set(newValue_1)。注意,EquilateralTriangle类的构造器,有三个不同的步骤:
1、为子类中申明的属性(sideLength)赋值
2、调用父类的构造器
3、改变在父类中定义的属性的值。任何额外的初始化步骤,譬如调用使用方法,getters或者是setters,也能在这个时间点中进行。
要修改从父类继承的属性,或者是调用方法(类方法除外),都要先调用super的init方法。否则,self是未初始化的,会导致错误。

如果你不需要对属性进行计算,但是你仍然给出一段代码,希望在属性将设置一个新的值之前,或者已经设置了一个新的值之后运行,那么你可以使用willSet和didSet。任何时候(构造器之外),只要属性的值发生了变化,你提供的代码都会运行。例如,下面的类中,确保类的三角形(属性)的边长总是和他的正方形(属性)的边长相等。例:


willSet/didSet

当遇到可选值的时候,例如方法,属性和下表,你可以在操作符前使用 "?"。如果"?"前的值是nil,那么所有在"?"之后的(代码,逻辑)都会被忽略,同时整个表达式是nil的;否则(即不为nil),可选值是被拆包的(unwrapped),并且所有"?"之后的行为都使用拆包后的值。在两种情况下整个表达式的值是一个可选值。例:


optional value

所谓可选值,指的是这个值可能为空或者不为空,而不是说这个值的类型是可变的。为空的话,"?"后面的部分不会执行。譬如,例中的optionalSquare?.sideLength。如果,optionalSquare是空的,那么sideLength属性不会被调用,而且作为左值的sideLength也是nil。

相关文章

  • Swift3.x - 类和结构体

    类的介绍和定义 Swift也是一门面向对象的开发语言。 面向对象的基础就是类,类产生对象。 Swift如何定义类:...

  • 接上面的基础语法(Swift中类的使用)

    类的介绍和定义 1.Swift 也是面向对象的语言,面向对象的基础是类,类产生的对象,那么Swift中如何定义类呢...

  • 13-Swift中的类

    一、类的介绍和定义 Swift也是一门面向对象开发的语言,面向对象的基础是类,类产生了对象; 在Swift中定义类...

  • Swift中类的使用

    一. 类的介绍和定义 Swift也是一门面向对象开发的语言面向对象的基础是类,类产生了对象在Swift中如何定义类...

  • swift —— 对象和类

    使用 'class' 关键字后跟类名来创建一个类。在一个类中,申明一个属性的写法,同申明一个常量或变量的写法是一样...

  • Swift对象和类

    Swift的对象和类 使用 class 和类名来创建一个类。 类中属性的声明和常量、变量声明一样,唯一的区别就是它...

  • 12 类

    1. 类的介绍和定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定...

  • Swift基础小结2

    类一、类的介绍和定义 swift也是一门面向对象开发的语言2.面向对象的基础是类,类产生了对象3.在swift中如...

  • Swift中类的定义

    Swift中类的定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定...

  • Swift 是一门什么样的语言

    Swift 既是面向对象的,又是函数式的编程语言。 Swift是面向对象的语言。 Swift支持类的封装、继承和多...

网友评论

      本文标题:swift —— 对象和类

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