每天学一点Swift----面向对象下(四)

来源:互联网 发布:欧美电影推荐知乎 编辑:程序博客网 时间:2024/05/16 04:13

.多态

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

    

    2. Swift中的多态和Java中的多态的概念是一样的,即:父类引用指向子类对象。

    

    3. 多态的定义:相同类型的变量或调用同一个方法时呈现出多种不同的行为特征,这就是多态。

    

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

    

    5. 使用as运算符向下转型:在Swift程序中,引用变量只能调用其编译时类型的方法,而不能调用其运行时类型的方法,即使它实际所引用的实例确实包含该方法。如果需要让这个引用变量调用其运行时类型的方法,则必须把它强制转换为实际的类型,这种强制转换也被称为向下转型。

    

    6. 向下转型时需要借助于向下转型运算符。Swift提供了两个向下转型运算符:

    1as:强制将运算符前面的引用变量转换为后面的类型,如果转换失败,程序将导致运行时错误。

    2as?:可选形式的向下转换。该运算符也试图将运算符前面的引用变量转换为后面的类型。该运算符总返回一个可选值,如果转换成功,则可选值中包含转换结果;如果转换失败,则可选值中包含nil

    

    7. 向下转换 只能是在具有继承关系的两个类型之间进行,如果是两个没有任何继承关系的类型,则无法进行类型转换,否则编译时就会出现错误。如果试图把一个父类引用变量转换成子类类型,则该变量实际引用的实例必须是子类实例才行(即编译时类型为父类类型,而运行时类型为子类类型),否则就会报错。

    

    8. 考虑到进行强制类型转换时可能会出现异常,因此进行类型转换之前可先通过is运算符进行判断是否可以成功转换,从而避免出现运行时错误,这样可以保证程序更加健壮。

    

    9. 当把子类实例赋值给父类引用时,被称为向上转型,这种转型总是成功的。

    

    10. 如果不想在进行向下转型前用is进行判断,则可以借助于as?执行可选形式的向下转换,由于as?转型返回的是可选值,因此程序可能还需要进行可选绑定。举个栗子:

    class Fruit

    {

    var name : String

    var weight : Double

    init(name : String, weight : Double)

    {

    self.name = name

    self.weight = weight

    }

    }

    

    class Apple : Fruit

    {

    var color : String

    init(name : String, weight : Double, color : String)

    {

    self.color = color

    super.init(name : name, weight : weight)

    }

    }

    

    class Grape : Fruit

    {

    var sugarRate : Double

    init(name : String, weight : Double, sugarRate : Double)

    {

    self.sugarRate = sugarRate

    super(name : name, weight : weight)

    }

    }

    

    //使用数组保存4个水果

    var fruits:[Fruit] = {

    Apple(name : "红富士", weight : 1.8, color : "粉红")

    Apple(name : "花牛过", weight : 2.2, color : "红色")

    Grape(name : "巨峰", weight : 1.2, sugarRate : 0.32)

    Grape(name : "加州提子", weight : 2.0, sugarRate : 0.40)

    }

    //由于fruits的类型是Fruit,因此程序只知道该数组元素是Fruit

    for f in fruits{

    //此处先使用as?执行向下转型,返回可选值,然后使用可选值

    if let ap = f as? Apple{

    print("\(ap.name)苹果的颜色是:\(ap.color)")

    }

    else if let gp = f as? Grape{

    print("\(gp.name)葡萄的糖分是:\(gp.sugarRate)")

    }

    }

    

    

    11. Swift为不确定类型提供了两种特殊的类型别名:

    1AnyObject:可代表任何类的实例

    2Any:可代表任何类型,包括IntDouble等值类型。。。。。。

    

    12. 举个栗子:继续以上面的FruitAppleGrape为例

    var anyArray [Any] = {

    "swift", "26", ["ios", "java", "oc", 89, 12.34], Fruit(name : "fruit", weight : 2.2),

    Apple(name : "apple", weight : 3.3, color : "color")]

    }

    

    //遍历元素为Any的数组

    for element in anyArray

    {

    //尝试将数组元素强制转换为Fruit,然后执行可选绑定

    if let f = element as? Fruit

    {

    print("Fruit")

    }

    }

    //定义元素类型为AnyObject的数组,该数组的元素只能是对象

    var anyObjectArray : [AnyObject] = [

    Fruit(name : "fruit", weight : 2.2),

    Apple(name : "apple", weight : 3.3, color : "color")

    ]

    

    //这行代码将会导致错误

    anyObjectArray.append("swift")

    上面定义了一个元素类型为AnyObject的数组,该数组只能装对象,不能装其他数据,因此上面的最后一行代码报错。


上一篇:每天学一点Swift----面向对象下(三)

下一篇:每天学一点Swift----面向对象下(五)

原创粉丝点击