• swift学习笔记->类型转换,协议与扩展


    类型转换有两种情况

    1.没有任何关系两个类型之间的转换

    2.继承链条里的向上与向下转型

     第一种 举个例子  int 与 string 类型  两个不相关的类型  依赖他们自身的方法进行转换

    let i = 3
    let str = "(i)"
    let str2 = String(i) 

    第二种  类的继承链中的转换

    class Parent{
        var p = 1
    }
    
    class Child: Parent {
        var c = 2
    }
    
    let pins: Parent = Child()

    这是子类转化为父类  能转换  但是转换后只能访问父类属性方法而不能使用子类的属性方法

    is 判断是否可转换类型(相同类型)返回true  or false

    class Parent{
        var p = 1
    }
    
    class Child: Parent {
        var c = 2
        func aaa(){
            print("aaa")
        }
    }
    let test = Child()
    test is Child    //true
    test id Parent //true

    as进行类型转换  返回 可选的(Optional)  需要解封才能使用

     var pins: Parent = Child()

    let cins = pins as? Child //返回的是Optional
    cins?.c

    也可以在转换时隐式解封

    var pins: Parent = Child()
    var cins = pins as! Child //返回的是Optional
    cins.c

    协议 protocol 

    swift的协议相当于java的借口   也是一个抽象的类型  通过它能实现依赖倒转(参考C语言中提到的依赖倒转原理)

    协议如何定义呢

    protocol test{
        var a:Int{
            get
            set
        }
        var b:Int {
            get
        }
        func add();
    }

    这是一个简单地协议(接口) 

    协议要注意以下几点

    1.一个协议可以要求任何符合类型提供一个实例属性或类型属性与一个特定的名称和类型。协议不指定是否该属性应该是一个存储属性或者计算属性--它只指定所需的属性名称和类型。协议还制定是否每个属性必须可获取或可获取和可设置。

    2.如果一个协议需要一个属性是可获取和可设置的,那么一个常量存储属性或一个只读的计算属性是无法满足此属性要求的。如果协议之需要一个属性是可获取的,那么任何类型的属性都能满足此要求,并且如果这对你代码有用,它同样是有效的,也是可设置的。

    3.属性要求总是声明为变量属性,用var关键字做前缀。可获取和可设置属性是通过在他们类型声明后编写{ get set }方法,并且可获取属性是通过编写{ get }方法。

    4.只能在协议中用static修饰静态属性。但在实现类型可以用class 也可以用static,实现这个协议就必须实现协议中所有的属性方法

    5.添加方法时 只需要方面名 参数  返回值 ,不需要实现方法内部代码块 , 默认值不能在协议中指定

    6.协议中得方法可以添加mutating,在类中得实现中,可以不需要mutating,在值类型中得实现中就必须加mutating

    协议的继承

    protocol test1{
        var a:Int {
            get
        }
        func add()
    }
    protocol test2:test1{
        var b :Int {
            set
            get
        }
        func sum(a:Int,b:Int)
    }
    class test : test2{
        var a:Int{
            return 100
        }
        var b:Int{
            set{
            
            }
            get{
                return 200
            }
        }
        func add() {
            print("add")
        }
        func sum(a: Int, b: Int) {
            print(a+b)
        }
    }

    从例子可以看出  协议的继承与类的继承是一样的

    如果一个类 拥有一个父类 又必须实现好几个协议呢?

    只要把父类放在引号后面第一位   之后逗号隔开协议就可以了

    protocol test1{
        
    }
    protocol test2{
    
    }
    class parent{
    
    }
    class test : parent , test1 , test2{
        
    }

    协议中定义了什么  类就实现什么

    扩展(extension)

     1. 可以用来扩展类,结构,枚举,协议等(即使这些你没有源代码,系统的都可以)

     2. 可以增加但不能重写已存在的功能

    ------------------------

     1. 可以添加实例计算属性与静态计算属性(比如给double类型添加一些表示长度单位的计算属性)

     2.添加实例方法与类方法

     3.提供新的初始化方法。

       1.可以让别的类型作为新增init的参数

       2.或其它的init选项

     4.给值类型通过扩展添加init,也可以保留在原值类型中由编译器自动添加的各种init

     5.增加下标

     6.让已存在的类型实现一个协议

    不能:

    1. 不能添加存储属性(应该是对 init 的影响)

    2. 不能给属性添加观察者

    3. 不能给类添加特定的初始化器

    4. 不能给类添加析构函数

    举个例子  下面是给Int类型进行扩展

    extension Int {
        var m: Int {
            return 1
        }
        var km: Int {
            return self * 1000
        }
    }
    
    let i = 20
    
    
    i.m
    i.km
  • 相关阅读:
    Git 思想和工作原理
    scala 内部类
    nginx -stream(tcp连接)反向代理配置 实现代理ldap转发
    【转载】Keepalived安装使用详解
    【转载】Linux内存中buffer和 cached的比较
    【转载】Vmware Vconverter从物理机迁移系统到虚拟机P2V
    InfluxDB 备份和恢复
    Mongodb 主从同步
    Redis主从同步
    ActiveMQ 高可用集群安装、配置(ZooKeeper + LevelDB)
  • 原文地址:https://www.cnblogs.com/pengser/p/4975885.html
Copyright © 2020-2023  润新知