swift-多态

  • 前言

swift引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明改变量是使用的类型决定,编译器只认每个变量编译时类型;运行时类型由实际赋给该变量的实例决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态(Polymorphism)。

  • 多态性

相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这既是多态。(可以联系继承来理解)
编译时多态:方法重载,都是编译时多态。
运行时多态:p.toString()方法,并不能确定是父类的toString()方法,还是子类的。运行时在确定。

  • 使用is运算符检查类型

is运算符的前一个操作数通常是一个引用类型变量,后一个操作数通常是一个类(也可以是协议,可以把协议理解成一种特殊的类),它用于判断前面的引用变量是否引用后面的类,或者其子类、实现类的实例。如果是,返回true。否则返回false。

  • 使用as运算符向下转型

as:强制将运算符前面的引用变量转换成后面的类型,如果转换失败,程序将导致运行时错误。
as?:可选类型的向下转换。可选值中包含nil。

  1. 向下转换只能在具有继承关系的两个类型之间进行。
  2. 考虑到进行强制类型转换时可能出现异常,因此进行类型转换之前可先通过is运算符来判断是否可以成功转换。这样可以使程序更加健壮。
  3. 当把子类实例赋给父类引用变量时,被称为向上转型,这种转型总是可以成功的。
  • Any和AnyObject

swift为不确定类型提供了两种特殊的类型别名:
1、AnyObject:可代表任何类的实例。
2、Any:可代表任何类型,包括Int、Double等值类型。

  • 嵌套类型

swift允许在一个类型的内部(即{}内部)定义另一个类型,这种机制被称为嵌套类型。
需要说明的是,嵌套类型不允许使用static或class修饰,也就是说,嵌套类型没有所谓的“类型相关的嵌套类型”。

提示:
在Java语言中,与嵌套类型类似的机制被称为内部类;在C++语言中,与嵌套类型类似的机制被称为嵌套类。

  • 扩展

扩展是swift的一种动态特征,swift允许使用扩展为现有的类添加新方法,并且不需要创建子类,不需要访问原有类的源代码。但因为扩展不是派生子类,所以扩展不支持重写。
扩展的定义语法为:

[修饰符] extension 已有类型
{
      //添加新功能
}

上面的修饰符可以忽略。
若需通过扩展让已有的类型遵守一个或多个协议,语法格式如下:

[修饰符] extension 已有类型: 协议1, 协议2
{
      //实现协议方法
}
  • 协议

用于定义多个类型应该遵守的规范。swift协议的作用,就相当于其他语言中接口的作用。
语法格式如下:

[修饰符] protocol 协议名: 父协议1, 父协议2
{
      //协议内容
}

合成协议:
swift允许将多个协议合成一个临时的类型,这种用法被称为合成协议。
语法格式如下:

protocol <父协议1, 父协议2, ...>

唯类(Class-Only)协议:
这种协议只能被类实现,不能被枚举、结构体实现。其定义方式,只要在定义协议的协议名后的冒号后面添加class关键字即可(class放在所有父协议的第一位)。
语法格式如下

protocol 协议名: 父协议1, 父协议2
{
      //唯类协议的定义
}

可选协议:
可以选择不实现的协议。可选协议必须添加@objc修饰,协议成员前添加optional关键字即可定义可选协议。可选协议一定是唯类协议(因为它只能被类实现,不能被枚举、结构体实现)。

注意:

  1. 协议支持形参个数可变的方法,但不支持为形参指定默认值。
  2. 如果协议中定义的方法没有使用mutating修饰(没有变成可变方法),枚举、结构体实现该协议,并实现该方法是就不能添加mutating。简单的说,可变、非可变方法都可实现协议中的可变方法;但只有非可变方法才能实现协议中的非可变方法。
  3. 协议能要求实现者必须提供哪些下标,也能要求该下标是否有setter部分和getter部分。
  4. 只有使用类实现协议中定义的构造器时,才需要使用required;使用枚举、结构体实现协议中的构造器则没有这些要求。

你可能感兴趣的:(swift-多态)