• Swift中的结构体,类,协议,扩展和闭包的用法以及? 和 !的区别


    // MARK: - 1.结构体

    //1.声明一个结构体

    struct Rect {
        // 声明结构体变量的属性(存储属性)
        var x:Float
        var y:Float
        var Float
        var height:Float
        // 声明结构体属性,要使用static
        static var description:String?
        
        // 声明一个计算属性(是用来专门计算结构体变量属性的setter,和getter方法,其本身没有存储功能)
        var centerX:Float {
            // set方法
            set {
                x = newValue
            }
            
            //get方法 (必须得有)
            get {
                return x / 2
            }
        }
        
        var centerY:Float {
            get {
                return y / 2
            }
        }
        // 声明方法
        // 声明一个结构体变量方法 (相当于OC中的实例方法)
        func frameIntfor() {
            print("x:(x),y:(y),(width),height:(height)")
        }
        // 声明一个结构体方法(相当于OC中类方法),使用static修饰
        static func infor() {
            print("这是结构体方法")
        }
        
        
        
    }

    // 1.根据结构体去定义一个结构体变量
    var frame = Rect(x: 10, y: 10, 100, height: 100)
    // 2.访问结构体变量中的属性
    // 注意:结构体变量的属性类型可以使用let去修饰,但是访问的时候不能修改
    frame.x = 20
    print(frame.x)

    //3.访问结构体属性
    Rect.description = "我是结构体属性"
    print(Rect.description)

    // 4.访问计算属性
    frame.centerX = 200; // 这句话就相当于在调用centerX的setter方法
    let value = frame.centerX // 这句话就相当于在调用centerX的getter方法
    print(value)

    // 5.调用结构体变量的方法
    frame.frameIntfor()
    // 6.调用结构体方法
    Rect.infor()

    // MARK: - 2.类 (class)
    class Person {
        var name:String?
        var age:Int?
        // 构造初始化方法
        init(name:String,age:Int) {
            self.name = name
            self.age = age
        }
        // 自定义初始化方式
        init (name:String) {
            self.name = name
        }
        // 声明类属性
        static var introduce:String?
        
        // 声明计算属性
        var value:Int {
            set(a) {
                age = a // 在写计算属性的时候,一定不能出现self,否则会造成死循环
            }
            get {
            return age!
    }
        }
        // 声明类方法的两种方法
        // 1.在类方法前加上static修饰 [虽然是一个类方法,但是该方法在子类中不能进行重写]
        static func sayHi() {
            print(introduce) // 注意:在类方法中只能使用类属性,不能使用对象属性
        }
        // 2.在类方法前加上class修饰 [它是一个类方法,可以被子类重写]
        class func sayHello() {
            print(introduce)
        }
        // 声明一个实例(对象)方法
        func sayHi2() {
            print("hell,我是实例方法")
        }
    }

    // 1.创建对象 [此时应该注意和OC区分开,实例对象名,: 后边跟的是类] (注意: 要初始化对象一定要写初始化构造的方法)
    var person1:Person = Person(name:"MBBoy", age:20)

    // 2.访问类中的属性
    print(person1.name!)

    // 3.访问类中的属性(对象属性)
    Person.introduce = "我是XXX"
    print(Person.introduce!)

    // 4.访问计算属性
    person1.value = 28
    print(person1.value)

    // 5.访问类方法
    Person.sayHi()
    Person.sayHello()

    // 6.访问实例方法
    person1.sayHi2()

    //定义一个子类,继承Person
    //在Swift中不支持多继承
    class Student:Person {
        // 重写父类的方法
        // 重写父类中的类方法
        override class func sayHello() {
            print("我是子类Student类,重写了父类的类方法")
        }
        // 重写父类中的实例方法
        override func sayHi2() {
            print("我是子类Student类,重写了父类的对象方法")
        }
    }

    // 初始化Student对象
    var student = Student(name: "张三", age: 25)

    Student.sayHello()
    student.sayHi2()

    // MARK: - 3.值类型和引用值类型的区别

    // 值类型
    /*
    struct animal {
        var name:String?
        var age:Int?
        init(name:String,age:Int) {
            self.name = name
            self.age = age
        }
    }

    var dog = animal(name: "贝贝", age: 3)
    var dog1 = dog // 此时将dog的数据拷贝给dog1
    dog.name = "欢欢"
    print("dog.name:(dog.name), dog1.name:(dog1.name)")

    */


    // 引用值类型
    class animal {
        var name:String?
        var age:Int?
        init(name:String,age:Int) {
            self.name = name
            self.age = age
        }
    }

    var dog = animal(name: "贝贝", age: 3)
    var dog1 = dog

    dog.name = "欢欢"
    print("dog.name:(dog.name!),dog1.name:(dog1.name!)")

    // MARk: - 4.协议(Protocol)

    // 当Swift中声明协议的时候,协议里有可选方法需要使用@objc关键字修饰
    @objc protocol MarryDelegate {
        
        func cook() // 做饭
        func wash() // 洗衣服
        optional func hitDouDou() // 打豆豆
        
        
    }

    protocol DivorceDelegate {
        func DivideMoney() //分割财产
        
    }

    // 如果一个类要遵循协议的时候,如果这个类有父类,要在:后先写父类,然后在写遵循的协议
    class Man: Person,MarryDelegate,DivorceDelegate {
        @objc func cook() {
            print("还好去新东方学了几年的厨艺,用于可以大展身手")
        }
        
        @objc func wash() {
            print("还好买了台洗衣机")
        }
        func DivideMoney() {
            print("分财产")
        }
        
    }

    // 创建一个男人
    let man = Man(name: "韦小宝", age: 22)

    man.cook()
    man.wash()
    man.DivideMoney()

    // MARK: - 5.扩展 (Extension)
    // 1.扩展协议中的相关方法
    extension Man {
        @objc func hitDouDou() {
             print("老婆,我在打豆豆")
        }
    }

    man.hitDouDou()

    // 2.扩展还可以扩展类方法(给某一个类添加方法,类似于OC中的Category类目)和对象方法

    extension Man {
        // 扩展一个对象方法
        func sing() {
            print("老婆老婆,我爱你")
        }
        // 扩展一个类方法
        class func sleep() {
            print("多喝水,早点睡")
        }
    }

    man.sing()
    Man.sleep()

    // MARK: - 6.闭包

    // 求两个数的最大值
    /*
    在OC中使用Block实现

    int (^myBlock)(int num1,int num2)  = ^int(int num1,int num2){
    return num1 > num2 ? num1 : num2;

    }

    */

    // 使用闭包
    var myBlock : ((num1:Int,num2:Int)->Int)

    // 第一种使用方式
    myBlock = {
        (num1:Int,num2:Int)->Int in // 切记不能忘记in
        
        return num1 > num2 ? num1 : num2
    }

    // 第二种方式
    myBlock = {
        num1,num2 in
        return num1 > num2 ? num1 :num2
    }

    // 第三种
    myBlock = {
        num1,num2 in
        
        num1 > num2 ? num1 : num2
    }

    // 第四种

    myBlock = {
        $0 > $1 ? $0 : $1
    }

    // 第五种

    myBlock = {
        (num1,num2)->Int in
        return num1 > num2 ? num1 : num2
    }

    let max = myBlock(num1: 88, num2: 66)
    print(max)

    // MARK: - 7.?和! 的区别
    // ? 代表可选类型,其实质是一个枚举类型,里边有None和Some两种类型,其实nil值相当于Optional.None,如果有值相当于Optional.Some
    // ? 有值, 没值 (nil)

    // ! 强制解包

    var number : Int? = 8

    // 如果对没值 (nil)的变量进行强制解包的情况下会造成崩溃
    var number1 = number!

    print(number1)

    // 可选绑定,不用强制解包
    if var number2 = number
    {
        print(number2)
    }

    // !隐式解析可选类型: 有值,没值 (nil)
    // 如果! 强制解析没值的变量,也会造成崩溃

    var intNumber :Int! = 10

    var intNumber1 = intNumber
    print(intNumber1)

    // 可选绑定
    if var intNumber2 = intNumber
    {
        print(intNumber2)
    }










  • 相关阅读:
    SPRING-BOOT系列之简介
    SPRING-BOOT系列之Spring4快速入门
    Java网络编程
    python中cursor操作数据库(转)
    TextView显示HTML文本时<IMG>标签指定图片的显示处理
    DBCP连接池介绍
    spring中propertyplaceholderconfigurer简介
    NoSQL 数据建模技术(转)
    分布式服务框架 Zookeeper -- 管理分布式环境中的数据(转载)
    Linux下MySQL5.6的修改字符集编码为UTF8
  • 原文地址:https://www.cnblogs.com/leikun1113/p/5521824.html
Copyright © 2020-2023  润新知