美文网首页
Swift(结构与枚举,继承与多态,协议,字符串,集合类型) g

Swift(结构与枚举,继承与多态,协议,字符串,集合类型) g

作者: AAup | 来源:发表于2016-05-14 09:54 被阅读254次

    上一回http://www.jianshu.com/p/fe204df5e1f5

    ------结构与枚举

    ---结构

    红色重点

    class RPoint{
    var x:Int
    var y:Int
    
    init(x:Int, y:Int){
        self.x=x
        self.y=y
    }
    
    deinit{
        print("clean up")
    }
    }
    
    struct SPoint{
    var x:Int
    var y:Int
    var z:RPoint
    
    }
    var rp=RPoint(x:10, y:20)
    
    //struct有默认按成员初始化器
    var sp1=SPoint(x:10, y:20, z: RPoint(x: 100,y: 200))
    
    var sp2=sp1
    print(" \(sp1.x), \(sp1.y), \(sp1.z.x), \(sp1.z.y)")
    print(" \(sp2.x), \(sp2.y), \(sp2.z.x), \(sp2.z.y)")
    sp1.x+=10
    sp1.y+=10
    sp1.z.x+=10
    sp1.z.y+=10
    //会发现2的x,y没有随1的x,y改变而改变.
    //但是2zx,zy就随着1的zx,zy 改变而改变.
    //随意关于数据修改方面 不要在struct内定义引用类型
    print(" \(sp1.x), \(sp1.y), \(sp1.z.x), \(sp1.z.y)")
    print(" \(sp2.x), \(sp2.y), \(sp2.z.x), \(sp2.z.y)")
    

    ---结构与类的相同点与不同点(struct VS Class)

    ---枚举类型

    //定义枚举类型
    enum Color {
    case Red
    case Green
    case Blue
    }
    enum ComplexColor{
    case Red,Green,Blue,Alpha
    }
    
    //枚举的使用
    var c1=Color.Red
    var c2:Color
    c2 = Color.Green
    c1 = .Blue
    var c3=c1
    
    //全局函数使用枚举类型
    func print(color: Color){
    //switch类型要包含所有枚举类型
    switch color {
    case .Red:
        print("Red Color!")
    case .Green:
        print("Green Color!")
    case .Blue:
        print("Blue Color!")
        
    //default:(可以省略剩余的)
        //print("剩余的")
    }
    
    }
    
    //基本属于用于计算性
    //指定原始类型
    enum WeekDay: Int{//类型只能是字符,字符串,整数.或者浮点数
    case Monday=1, Tuesday, Wednesday,Thursday, Friday, Saturday, Sunday
    }
    
    var day: WeekDay?
    day = WeekDay(rawValue: 7)
    
    
    var data=WeekDay.Saturday.rawValue
    
    
    class Point{
    var x=0
    var y=0
    
    init(x:Int, y:Int){
        self.x=x
        self.y=y
    }
    }
    
    //枚举关联值
    enum Position{
    case Number(Point)
    case Name(String)
    }
    
    var p1=Position.Number(Point(x: 123,y: 588))
    var p2=Position.Name("Shanghai People's Square")
    
    func print(position: Position){
    
    switch position {
    case .Number(let number):
        print("[\(number.x), \(number.y)]")
    case .Name(let name):
        print(name)
    }
    
    }
    
    print(p1)
    print(p2)
    

    ------继承与多态

    Snip20160515_25.png
    struct Point{
    var x=0
    var y=0
    }
    
    class Shape{
    var no=0
    
    func move() {
        print("NO: \(no) Shape.move")
    }
    }
    
    
    class Rectangle: Shape{
    var leftUp=Point()
    var width=0
    var height=0
    
    }
    
    class Circle: Shape{
    var center=Point()
    var radius=0
    }
    
    
    func process(shape: Shape){
    shape.no += 1
    shape.move()
    }
    
    var r1=Rectangle()
    var c1=Circle()
    
    //成员复用
    r1.no += 1
    r1.move()
    
    c1.no += 1
    c1.move()
    
    //类型抽象
    process(c1)
    process(r1)
    
    var s:Shape
    s=c1
    s=r1
    
    class Shape{
    var no=0
    //0x000340
    final func show(){
        print("Shape.show")
    }
    //0x000640
    func move() {
        print("Shape.move")
    }
    }
    
    //override多态定义
    //Rectangle 重写
    class Rectangle: Shape{
    override var no: Int {
        get{
            print("Rectangle.no.get()")
            return super.no
        }
        set{
            print("Rectangle.no.set()")
            super.no=newValue
        }
        }
    
        //0x000880
        override func move() {
        print("Rectangle.move")
        }
    
    }
    
    //override多态定义
    class Circle: Shape{
    override func move() {
        print("Circle.move")
    }
    }
    
    func process(shape: Shape){
    shape.no += 1
    shape.move() //根据实际类型来调用
    }
    
    //变量有双重身份:
    //1. 声明类型
    //2. 实际类型
    var sp: Shape
    sp=Shape()
    sp.move() // JMP  GetVirtualMethod(sp) 二次指针间接运算
    sp.show() // JMP  0x000340
    
    //换实际类型
    sp=Rectangle()
    sp.move() // JMP  GetVirtualMethod(sp) 二次指针间接运算
    process(sp)
    
    sp=Circle()
    sp.move()
    
     process(sp)
    
    class Base{
    var data1:Int
    init(){
        data1=100
        print("\(data1)")
        print("Base.init")
    }
    
    deinit{
        print("Base.deinit")
    }
    }
    
    class Sub1: Base{
    var data2=200
    //自动继承base的初始化器
    //自动继承父类的析构器
    }
    
    class Sub2: Base{
    var data2=200
    //不继承Base初始化器,使用自己的初始化器
    
    //override 初始化器的原型一致的时候使用
     override init(){
        super.init()//手动调用父的初始化器,还有想调用父类的属性也要手动
        //不调用回自动生成
        print("\(data1), \(data2)")
        print("Sub.init")
    }
    deinit{
        //子类调用完 会自动调用父类的析构器 super.deinit
        print("Sub.deinit")
    }
    }
    
    func process(){
    var a:Base
    a=Base()
    print("----------")
    
    var b:Base
    b=Sub1()
    print("----------")
    
    var c:Base
    c=Sub2()
    print("----------")
    }
    
    process()
    

    ------协议

    协议很少使用到静态属性

    struct 实例方法要加上mutating

    ---协议变量的内存模型遵从实际类型的内存模型

    引用类型传值.拷贝采用传引用方式
    值类型传值.采用拷贝传值方式

    ---检查协议类型

    使用is检查类型是否实现了协议
    使用as?和as!将类型下追溯转型为协议

    protocol AProtocol {
    func display()
    }
    
    class Base {
    var no = 0
    }
    
    class sub: Base,AProtocol {
    func display() {
       print(no)
    }
    }
    
    //Compilt-time  Type = 编译时类型,声明类型
    var  item1 , item2:Base
    //Runtime Type = 运行时类型,实际类型
    item1 = Base()
    item2 = sub()
    
    if (item1 is AProtocol){
    print("item1是AProtocol的基类")
    }
    if (item2 is AProtocol){
    print("item2是AProtocol的基类")
    }
    
    var item3:AProtocol?
    var item4=sub()
    
    //item3 = item1//不能写,因为var item3:AProtocol? 而item1 :base
    item3 = item1 as? AProtocol //as?多态转型
    item3 = item2 as? AProtocol
    
    item3 = item4
    

    ---协议中的属性

    --协议可以定义只读属性,也可以定义读写属性
    --协议可以定义实例属性,也可以定义类型属性
    --协议中只能定义变量属性,不能定义常量属性
    --实现协议并不要求实现为储存属性还是计算属性

    ---协议中的方法

    -协议可以定义实例方法,也可以定义类型方法
    --协议中方法不能定义参数默认值
    --针对值类型的mutating协议方法
    -值类型(struct and enum )实现的实例方法如果要更改实例本身,需要在协议方法的定义中标明mutating关键字,同时在方法实现时也添加mutating关键字
    -添加了mutating的协议方法,对类的实现方法无影响.在类内实现mutating协议方法时,无需再添加mutating关键字

    ---协议中的初始化器

    --协议可以定义初始化器,但是不能定义析构器
    --当class中实现协议定义的初始化器时候,需要添加required关键字
    -标明子类也需要提供该初始化器
    -如果定义为final类就不需要required关键字
    --协议可以定义可失败的初始化器 init?,具体实现时可以失败,也可以非失败

    ----更多协议形式

    ---协议继承

    --协议可以继承一个或者多个协议
    --实现子协议类型,也必须实现父类协议中约定成员

    ---协议组合

    --可以实现组合协议类型,使用protocol<A,B,.....>来组合多个协议
    --显示组合协议类型,必须实现组合协议中的每一个协议.
    --组合协议是一个临时类型

    ---可选协议

    --协议的某些成员可以定义为optional ,不必实现
    --可选协议只能应用于class,不能引用于struct和enumeration
    --可选协议必须表用@objc特性

    @import Foundation
    //协议继承
    protocol AProtocol{
    func display()
    }
    //B协议继承A协议
    protocol BProtocol:AProtocol {
    func invoke ()
    }
    protocol CProtocol {
    func excute ()
    }
    
    //ClassA BProtocol 要实现A协议的display也要同时B协议invoke
    class ClassA: BProtocol {
    func display() {
        print("dispaly")
    }
    func invoke() {
        print("invoke")
    }
    }
    
    class ClassB: AProtocol,CProtocol {
    func display() {
        print("dispaly")
    }
    func excute() {
        print("excute")
    }
    }
    
    //协议组合,临时类型
    func process (item:protocol<AProtocol,CProtocol>){
    //可以调用a.c协议其中一个
      item.display()
      item.excute()
    }
    
    var b = ClassB()
    process(b)
    
    @objc protocol DProtocol{
    optional var discription:String{get}
    optional func move()
    
    }
    // DProtocol成员里面添加optional   ClassC 就不用DProtocol实现成员
    class ClassC: DProtocol {
    
    }
    

    ------字符串

    //String是一个Struct,但内部包含一个指向堆上的"内容指针",其指向的对象存放真正的字符串内容
    
    var srt1:String = "Hello"
    var srt2 = "Hello,World"
    var srt3 = "I am programming in Swift"
    
    print(sizeofValue(srt1))
    print(strideofValue(srt1))
    print(sizeofValue(srt2))
    print(strideofValue(srt2))
    print(sizeofValue(srt3))
    print(strideofValue(srt3))
    
    import Foundation
    
    /*
     -----------------------------
     */
    //使用var和let控制字符串的可变性
    var str1 = "Hello"
    let str2 = ",Swoft"
    //str1+=str2
    //枚举字符
    for item in str1.characters{
    print(item)
    }
    
    for index in str1.characters.indices{
    print(str1[index])
    }
    
    print(str1.characters.count)
    print(str1[str1.startIndex])
    
    //不能提出某个字符
    //str1[1]
    
    //起始字母
    print(str1[str1.startIndex])
    //起始字母的下一个字符
    print(str1[str1.startIndex.successor()])
    //最后一个字符
    print(str1[str1.endIndex.predecessor()])
    
    //起始字母往后数第四个距离的子午
    let index = str1.startIndex.advancedBy(4)
    print(str1[index])
    
    /*
     -----------------------------
    */
    
    //链接字符串
    //1.用appendContentsOf
    str1.appendContentsOf(",World")
    //2.+ 和+=号
    var str3 = str1+str2
    
    str1+=str2
    
    //3.用append方法
    var char:Character="!"
    str1.append(char)
    
    
    //字符转义
    let heart = "\u{2665}"
    print(heart)
    //\t空出一个位置
    let work = "\tHello"
    print(work)
    
    //插值
    var x=100
    var y=200
    var text = "[\(x),\(y)]"
    
    //字符串比较
    var text1 = "Swift"
    var text2 = "Swift"
    var text3 = "swift"
    print(text1==text2)
    print(text1==text3)
    
    import Foundation
    
    var str1 = "Hello"
    var str2 = str1
    
    str1.appendContentsOf(",Work")
    print(str1)   
    print(str2)
    

    缓存容量与增长


    import Foundation
    
    var str = "Hello"
    print(str.characters.count)
    print(str)
    
    //分配好capacity
    str.reserveCapacity(10000)
    print(str.characters.count)
    

    ------集合类

    ----数组

    //数组声明与实例化
    var array1 = [1,2,3,4,5]
    var array2 :[Int]
    var array3:Array<Int>
    //--------------------
    class MyClass{
    init(){
        print("MyClass.init")
    }
    deinit{
        print("MyClass.deinit")
    }
    }
    
    var objectArray = [MyClass]()
    
    for _ in 1...5{
    objectArray.append(MyClass())
    }
    print(objectArray.count)
    ////清空元素
    objectArray.removeAll()
    
    //变量数组和常量数组
    var array5=[1,2,3]
    let array6=[1,2,3]
    array5.append(40)
    array5[3]=4
    print(array5)
    //数组操作
    for item in array5{
    print(item)
    }
    for(index,value) in array5.enumerate(){
    print("\(index),\(value)")
    }
    for index in 0..<array5.count   {
    print(array5[index])
    }
    
    var array7=array5+array6
    array5+=[5,6,7]
    print(array5.count)
    array5[4...6]=[6,7,8]
    print(array5)
    
    //加入元素
    array5.insert(5, atIndex: 4)//代价大
    print(array5)
    //删除元素
    array5.removeAtIndex(7)//代价大
    print(array5)
    
    //缓存容量
    var array8=[1,2,3]
    array8.reserveCapacity(120)
    for index in 4...100{
    array8.append(index)
    }
    //打印口可以清晰看见capacity 的呈倍数上次  最好是一开始定义好capacity的大小
    print("\(array8.count).\(array8.capacity)")
    
    Snip20160515_19.png
    //copy-0n-write
    var array9 = array1
    //未修改前array9 与array1 同一个指针
    array1[0]=10
    array1.append(20)
    //修改后array9与array1不同一个指针
    print(array1)
    print(array9)
    

    ----集合

    var words = Set<String>()
    //不能有重复元素
    words.insert("Hello")
    words.insert("Swift")
    words.insert("Language")
    words.insert("Hello")
    
    words.count
    words=[]
    words.count
    
    var cities1:Set<String>
    cities1=["Shanghai"]
    for city in cities1.sort(){
    print(city)
    }
    
    cities1.count
    //contains是否含有相同元素
    cities1.contains("New York")
    
    var ciries2:Set = ["New York","Shanghai"]
    print(cities1.isSubsetOf(ciries2))
    //remove清楚元素
    cities1.remove("Shanghai")
    //是否相等
    print(cities1==ciries2)
    //2是否含有1的元素
    print(cities1.isSubsetOf(ciries2))
    

    ----数组

    var dictionary1 = [String:Int]()
    var dictionary2 :Dictionary<String,Int>
    dictionary2=["jason":36,"tom":31,"Marty":44]
    
    for(name,age) in dictionary2{
    print("the age of \(name) is:\(age)")
    }
    for name in dictionary2.keys{
    print(name)
    }
    
    for value in dictionary2.keys{
    print(value)
    }
    
    dictionary2.count
    //修改元素, 一下两个性质是一样
    dictionary2["tom"]=32
    dictionary2.updateValue(33, forKey: "tom")
    //添加
    dictionary2["julie"]=28
    dictionary2.count
    //shan
    dictionary2["Marty"]=nil
    dictionary2.removeValueForKey("tom")
    dictionary2.count

    相关文章

      网友评论

          本文标题:Swift(结构与枚举,继承与多态,协议,字符串,集合类型) g

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