当前位置:网站首页>Swift 类型检查与转换

Swift 类型检查与转换

2022-04-21 07:14:00 秋秋小事

//
//  TypeCheckConversion.swift
//  SwiftCode
//
//  Created by Alisa on 2022/4/12.
//  Copyright  2022 Alisa. All rights reserved.
//

import Foundation

/*
 
    swift语言中,需要使用相应关键字来对实例的类型进行检查与转换,系统会帮助开发者监控此次类型转换是否成功
 
    数据类型的检查和转换需要使用is和as关键字,类型检查机制使程序代码更加健壮安全
 
 ** 类型检查
    is关键字:swift语言中要判断某个实例是否属于某个具体类型,可以使用is关键字,使用is关键字组成的判断语句将返回一个布尔值
            开发者可以根据布尔值的真或者假来判断类型检查结果是否匹配
 
    对于有继承关系的类,类型检查有如下原则:
        <1> 子类实例进行父类类型检查可以检查成功
        <2> 父类实例进行子类类型的检查不可以检查成功
        上面两条原则其实就是我们编程中常说的向下转换原则
 
    注意:is关键字有系统漏洞, 总报警告:'is' test is always true,还不清楚怎么解决
 
    
** 类型转换
    as关键字:关于类型转换,swift语言中使用的是as关键字
            与类型检查相似,swift语言中类型的转换有着向上兼容和向下转换的原则
    
    使用as做类型转换的两个原则:
        <1> 一个父类类型的集合可以接收子类类型的实例
        <2> 在使用第1条原则中父类集合中的实例时,可以将其转换为子类类型

*/

class Tree{
    
    let color:String
    var age:Int {
        willSet{
            print("age will set")
        }
        didSet{
            print("age did set value = \(self.age)")
        }
    }
    
    init(color:String, age:Int) {
        self.color = color
        self.age = age
    }
    deinit{
        print("Tree deinit")
    }
}

class PeachTree:Tree{
    
    var fruitColor:String
    var flowerColor:String
    var colorTemp:String{
        set{
            fruitColor = newValue
        }
        get{
            return fruitColor
        }
    }
    lazy var isHasFruit:Bool = false{
        willSet{
            if newValue {
                print("桃树结果子了")
            }
            else{
                print("桃树没有果子")
            }
        }
    }
    
    override init(color: String, age: Int) {
        self.flowerColor = "pink"
        self.fruitColor = "red"
        super.init(color: color, age: age)
    }
    
    convenience init(flowerColor:String, fruitColor:String) {
        self.init(color: "green", age: 10)
        self.flowerColor = flowerColor  //子类的变量需要函数在父类的构造函数调用之前赋值
        self.fruitColor = fruitColor    //子类的常量需要在父类的构造函数被调用后再赋值
    }
    deinit{
        print("PeachTree deinit")
    }
}

class WillowTree:Tree{
    
    //柳枝是否在摆动
    var swing:Bool{
        willSet{
            if newValue{
                print("柳枝在风中摆动")
            }
            else{
                print("柳枝停止摆动")
            }
        }
    }
    //是否在河边
    var byRiver:Bool{
        willSet{
            if newValue{
                print("柳树生长在河边")
            }
        }
    }
    
    override init(color: String, age: Int) {
        
        self.swing = false
        self.byRiver = false
        super.init(color: color, age: age)
    }
    
    convenience init(swing:Bool, byRiver:Bool){
        self.init(color: "green", age: 15)
        self.swing = swing
        self.byRiver = byRiver
    }
    deinit{
        print("WillowTree deinit!")
    }
}

class TypeCheckConversion{
    
    //简单的使用is判断一个变量的类型
    func useIsInstance(){
        
        //使用is时下面两种情况都有这种警告:'is' test is always true
        
        let tree = Tree(color: "green", age: 7)
        if tree.color is String{
            print("The tree color is String type!")
        }
        
        //一般is用于类型检查时,其实一般都去检查当前类型不确定,需要类型推断的实例,比如:
        let str = "HS"
        //进行实例的类型检查
        if str is String{
            print("str 的类型是String。")
        }
        
        /* 打印信息:
         The tree color is String type!
         str 的类型是String。
         Tree deinit
        */
    }
    
    //继承关系中的类型检查
    func inheritanceRelationship(){
        
        let tree:Tree = Tree(color: "green", age: 5)
        let peach = PeachTree(flowerColor: "pink", fruitColor: "light pink")
        
        //使用子类检查父类类型时,会返回true
        let isTree = peach is Tree
        if isTree{
            print("peach type ok!")
        }
        
        //使用父类检查是否为子类类型,会返回false
        let isPeachTree = tree is PeachTree
        if isPeachTree{
            print("true peach tree")
        }else{
            print("it is not peach tree")
        }
        
        /* 打印的信息:
         peach type ok!     子类被检查为父类的类型,返回true
         it is not peach tree   父类被检查为子类的类型 返回false
         PeachTree deinit   子类的析构函数先调用
         Tree deinit        父类的析构函数再调用
         Tree deinit        tree实例的析构函数调用
        */
    }
    
    //类型转换
    func transformType(){
        
        let tree = Tree(color: "green", age: 10)
        tree.age = 9
        let peach = PeachTree(flowerColor: "pink", fruitColor: "light pink")
        peach.age = 5
        let willow = WillowTree(swing: true, byRiver: true)
        willow.age = 6
        
        //将三个实例放在其公共父类类型的数组集合中
        let arrayOne:[Tree] = [tree, peach, willow]
        //进行遍历
        for itemOne in arrayOne{
            
            if itemOne is WillowTree{
                //进行类型转换
                let treeOne = itemOne as! WillowTree
                treeOne.swing = false
                continue
            }
            if itemOne is PeachTree{
                let treeOne = itemOne as! PeachTree
                treeOne.isHasFruit = true
                continue
            }
            if itemOne is Tree{     //这里又有警告:'is' test is always true
                print("当前类的类型本就为Tree类型,与数组初始化时元素类型一致!")
                continue
            }
        }
        
        /* 打印信息:
         age will set
         age did set value = 9
         age will set
         age did set value = 5
         age will set
         age did set value = 6      以上为公共基类属性age的willset的打印信息
         当前类的类型本就为Tree类型,与数组初始化时元素类型一致! array的第一个元素类型本就为Tree类型
         桃树结果子了     array的第二个元素类型转换PeachTree成功
         柳枝停止摆动     array的第三个元素类型转换WillowTree成功
         WillowTree deinit!
         Tree deinit
         PeachTree deinit
         Tree deinit
         Tree deinit
         
        */
    }
}

版权声明
本文为[秋秋小事]所创,转载请带上原文链接,感谢
https://blog.csdn.net/jiaoyangdetian/article/details/124308437