美文网首页
swift3.1 类和结构体

swift3.1 类和结构体

作者: 岁月蹉跎繁华落寞 | 来源:发表于2017-04-26 00:37 被阅读0次
    • 类和结构体的共同点

      a.定义存储属性
      b.定义函数
      c.定义下标,使用下表访问自己的值
      d.定义初始化设置自己的初始化状态
      e.扩展自己的功能
      f.实现协议提供某种特定的标准功能

    • 类和结构体的区别

      a.类可以继承,结构体不能继承
      b.类能够在运行时检查和解释类实例的类型
      c.Deinitializers使一个类的实例来释放任何资源分配
      d.类有引用计数,允许对象被多次引用

    // 定义类
    class StudentC{
      var name:String!
    }
    // 定义结构体
    struct StudentS{
        var name:String 
    }
    

    在类中定义属性必须要注意,如果你定义的存储属性不是可选值类型,必须进行初始化,不然编译会报错,但是结构体不会报错,因为系统默认会给结构体创建初始化方法

    // 定义类   
     class StudentC{
        static var des:String = "学生的类"
       var name:String!
        func getName()->String{
            return name
        }
    
        class func describe()->String{
            return des
        }
    
        static func getClassDescribe()->String{
            return des
        }
    }
    
    // 定义结构体
    struct StudentS{
        static var des:String = "学生的结构体"
        var name:String
        static func describe()->String{
            return "这是一个定义学生的类"
        }
    }
    

    类可以使用关键字static class 修饰方法,但是结构体只能使用关键字static修饰

    • 扩展下标
    class StudentC{
        var names:[String] = ["1","2","3","4","5"]
        subscript (index:Int)->String?{
            get{
                if names.count <= index{
                    return nil
                }
                return names[index]
            }
        }
    }
    
    // 定义结构体
    struct StudentS{
        var names:[String] = ["1","2","3","4","5"]
        subscript (index:Int)->String?{
            get{
                if names.count <= index{
                    return nil
                }
                return names[index]
            }  
        }
    }
    
    // 执行
    let student1 = StudentC()
    print(student1[8])
    
    • 初始化
     // 定义类
    class StudentC{
        var name:String
        init( name:String) {
            self.name = name
        }
    }
    
    // 定义结构体
    struct StudentS{
        var name:String
        init(name:String) {
            self.name = name
        }
    }
    let student1 = StudentC(name: "酷走天涯")
    let student2 = StudentS(name: "XUJIE")
    

    提示:

    结构体默认会有初始化方法

    struct StudentS{
        var name:String
    }
    let student2 = StudentS(name: "xujie")
    
    • 扩展功能
    extension StudentC{
      func describe()->String{
          return "学生" + self.name
      }
    }
    extension StudentS{
        func describe()->String{
            return "学生" + self.name
        }
    }
    
    • 实现协议
    // 定义一个协议
    protocol Capacity{
        func draw() // 协议方法
    }
    // 定义类
    class StudentC:Capacity{
        // 实现协议方法
        internal func draw() {
        }
        var name:String
        init( name:String) {
            self.name = name
        }
    }
    // 定义结构体
    struct StudentS:Capacity{
        // 实现协议方法
        internal func draw() {
        }
        var name:String
    }
    
    • 继承
    // 定义基类
    class Person{
         var name:String
        init( name:String) {
            self.name = name
        }
    }
    // 定义类
    class StudentC:Person{
        var score:Float
        init( name:String,score:Float) {
            self.score = score
            super.init(name: name)
            self.name = name
        }
    }
    

    提示:

    结构体不能继承结构体

    • mutating 关键字的作用

    结构体和枚举都是值类型,但是默认值类型的对象方法不能修改属性值,但是要修改怎么办呢?就必须在函数前面加mutating

    //例子1
    protocol Action{
        var myY:Int{ mutating get}
    }
    struct Point{
        var x:Int
        var y:Int
        // 结构体或者枚举修改值必须在函数前面加mutating
        mutating func modifyX(x:Int){
            self.x = x
        }
          // 注意计算属性,mutating 要加载getter方法前面
        var myY:Int{
            mutating get {
                self.y = self.y*2
                return y
            }
        }
     }
    // 例子2
    struct Point {
        var x = 0.0, y = 0.0
        mutating func moveBy(x deltaX: Double, y deltaY: Double) {
            self = Point(x: x + deltaX, y: y + deltaY)
        }
    }
     // 例子3
    enum TriStateSwitch {
        case off, low, high
        mutating func next() {
            switch self {
            case .off:
                self = .low
            case .low:
                self = .high
           case .high:
                self = .off
            }
          }
        }
    

    提示:

    1.计算属性setter方法不用修改属性值不用添加mutating
    2.计算属性setter方法中修改属性值的时候,一定要加mutating

    • 检测两个对象地址是不是相同
    class StudentC{
         var name:String
          init( name:String) {
              self.name = name
          }
      }
    let student1 = StudentC(name: "xujie")
    let student2 = student1
    if student1 === student2{
     print("地址相同")
    }
    

    运行结果:

    地址相同

    结论:

    类是引用类型,结构体是值类型,不能使用===/!== 判断地址

    • Deinitializers使一个类的实例来释放任何资源分配
    // 定义类
    class StudentC{
       var name:String
        init( name:String) {
                self.name = name
        }
         deinit {
        // 释放资源
        }
    }
    

    提示:

    结构体没有deinit 方法

    a. 什么时候用结构体

    1.该结构的主要目的是封装几个相对简单的数据值
    2.如果你希望你的结构在传递的时候被赋值而不是引用
    3.希望结构在传递的时候,内部的属性也被复制而不是引用
    4.不需要继承属性或者方法

    综合建议:

    结构体创建速度更快,内存占用更小,如果需要使用复杂的运算,这个时候,就需要综合考虑两者的有缺点了。

    相关文章

      网友评论

          本文标题:swift3.1 类和结构体

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