华山论剑之Swift初体验(二)

上一篇博客中,我写到关于Swift的变量,常量,数组,字典,元组,函数等一些基础知识,这一篇文章就谈一下关于结构体,类,协议,枚举,还有闭包的相关知识.

结构体和类


在Swift中结构体和类很相似,然后我们就先看一下结构体的相关知识吧

结构体

struct Frame {
    //存储属性 : 仅仅做存储值的作用
    
    var x : Float
    var y : Float
    var width : Float
    var height : Float
    
    //计算属性 : 通过计算获取到自己的值
    //设置属性的set和get方法
    //属性里面的set方法不能单独存在,必须有一个同属性的get方法存在后才可以写set方法
    var centerX : Float {
        get{
            return x + width/2
        }
        set{
            
            self.centerX = newValue
        }
    }
    
    var centerY : Float {
        get{
            return y + height/2
        }
        set{

            self.centerY = newValue
            
        }
        
    }
    
    //在Swift当中的结构体我们是可以创建一个初始化方法的
    //x为外部参数名,newX为内部参数名
    init(x newX : Float , y newY : Float , width newWidth : Float , height newHight : Float ) {
    
        self.x = newX
        
        self.y = newY
        
        self.width = newWidth
        
        self.height = newHight
    
    }
    
    //Swift的结构体中可以任意创建函数
    //如果需要在函数里卖弄修改属性的值的话,需要在函数的前面加上mutating关键字修饰
    mutating func helloWorld() {
    
    self.x = 100
    
    }
    
    //结构体属性
    //结构体属性是不能在普通的函数里面调用
    static  var name :String? = nil
    
    //结构体函数
    //结构体函数是可以调用结构体属性的
    //结构体函数里面不能调用普通属性
    //结构体函数里面可以调用本结构体存在的函数
    static func newPerson(name newName : String) {
    
    self.name = newName
        
    print(name)
    }
    
}

上面是结构体的定义,包括属性,结构体属性,init方法,普通函数 ,结构体函数,下面我们看一下在Swith中是如何调用结构体的初始化方法的,还有如何使用结构体.

//结构体函数的调用
//结构体函数,必须通过这个结构体进行调用
Frame.newPerson(name: "栋哥")

//第一种初始化方式,使用点语法,直接点出init方法
let frame:Frame = Frame.init(x: 100, y: 100, width: 100, height: 100)

print(frame.x)

//第二种初始化方式,直接结构体Frame加上参数
let frame1:Frame = Frame(x: 200, y: 200, width: 200, height: 200)

print(frame1.x)



对于OC中的类和Swith的类也是有很大区别的,看一下Swift中的类是如何定义的.

类的格式 :class 关键字 类名 { 类的实现 }

class Person {
    
    //在类里面创建一个属性的时候,必须要有初值,如果不想设置初值,就是设置成可选类型
    var name :String? = nil
    var age :Int? = nil
    
    //private 表示私有属性
    private  var gender: String? = nil
    
    //static 修饰的属性表示类属性
    static var country :String? = nil
    
    //Swift中类的初始化方法与结构体的初始化话方法有这惊人的相似,其实就是一样的.
    init(name newName :String, age newAge:Int ) {
    
        self.name = newName
        
        self.age = newAge
    
    }
    
    //实例方法里面不能直接调用类属性
    //实力方法可以直接对实例对象进行修改赋值
    //在函数声明之前加上一个privatemn  表示私有方法
    
    private func sayHi() {
    
        self.gender = "女"
    
    }
    
    //static 修饰的是类方法,是不可以被子类重写的
    static func sayHello() {
    
        self.country = "中国"

        print(self.country)
    
    }
    
    //class修饰分方法也是类方法,是可以被子类重写的.
    class func sayGod() {
        
        self.country = "栋哥的王国"
        
        print(self.country)
        
        
    }
    
    
}



//继承于父类的子类
class Student: Person {
    
    var number:Int? = nil
    
    //如果子类当中想要重写父类的方法,需要加override修饰
    override init(name newName: String, age newAge: Int) {
        
        super.init(name: newName, age: newAge)
        
        self.number  = 17
        
    }
    
    
   //使用class修饰的类方法是可以被子类修改的.
    override class func sayGod(){
    
    
    
    }
    
}


对于类和实例变量的调用我们与Swith中的结构体也是差不多的.

let person:Person = Person(name: "栋哥", age: 18)

print(person.age)

Person.sayGod()

看完了结构体和类,作为初学者的我们一定会懵,这么多惊人的相似,那我们就做一下对比
结构体
结构体书写是以struct开头的 类书写是以class开头的
结构体中的属性可以不设初值 类中属性必须设初值或者设置成可选类型
结构体中的函数如果想改变结构体中的属性,必须要加上mutating 修饰 类的方法中可以直接修改累得属性的值
结构体中没有私有函数这一说法 类中要想有私有方法,必须在方法的前面加上static或者class修饰


协议


在Swift中,协议和OC中也是存在很大区别的,OC中的协议室友必须实现的方法和选择实现的方法区分的,但是在Swift中则没有这个区别,只要是写在协议中方法必须实现,那么问题来了,如果我们想要有选择实现的方法怎么办? 还有就是当我们想要给我们写的系统类添加协议该如办呢? 下面我们就讲解协议的知识.

协议格式: protocol 关键字 协议名称
//在Swift的协议中没有必须实现的方法和选择实现的方法,而是只要是协议中的方法就必须要实现
protocol myDelegate {

    //协议方法前面加上mutating修饰的关键字之后,可以修改结构体里面的参数.而在类里面会自动忽略mutating!
mutating func goToSchool()


}

//为了解决可选实现方法的协议,我们可以使用OC中的代理
//在最前面用 @objc 修饰, 内部的方法用 optional 修饰可选实现的方法,其他的不变
@objc protocol TeacherDelegate {

optional func teachStudent()

}

//如果有继承关系 如下书写协议方式,父类必须在前!
//class 类名:父类,协议名称
class Teacher: Person,myDelegate {
    
    func goToSchool() {
        
        print("教学")
        
    }
    
}

//如果没有继承父类,则如下直接添加上协议名称
//class 类名: 协议名称
class NewTeacher: myDelegate {
    
    func goToSchool() {
    
        print("新教师报道")
        
    }
    
    
    
}

//结构体可以遵守协议
//但是结构体只能遵守Swift中的自己的协议,不能遵守OC中的协议
struct oldTeacher : myDelegate {

    var name:String
    
   mutating func goToSchool() {
        
        print("教师报道")
        
    }
    
}

对于想要给不能修改的类添加协议,我们可以使用延展extension来实现

//extension可以给一个类拓展新的协议,子类中就不能再次遵守协议和实现协议中方法!
extension Person : myDelegate {

    func goToSchool() {
        
    }
    
    //extension不可以添加新的属性,但可以添加新的函数
    //var height : Float ? = nil
    func dongGe() {
    
        
    }
    
}


枚举


就我个人而言,我对枚举是又爱又恨,爱其功能之强大,恨之虽然懂,但是不能很好的使用它.好了,对于懵逼的我又是怎么解释Swift中的枚举呢? 请看下面的代码.


enum time {
    
    case spring
    case summer
    case autumn
    case winter


}

//使用枚举的时候,初次给变量赋值,必须使用枚举名 . case名
var timer = time.spring

//第二次使用的时候 可以直接通过.case名使用
timer = .summer


//switch 搭配 枚举使用
//switch 的 value 要填写一个枚举类型的实例变量
//case.枚举的case名字
switch timer {

case .spring :
    
    print("春天")

case .summer:
    
    print("夏天")
    
case .autumn:
    
    print("秋天")
    
case .winter:
    
    print("冬天")

}


闭包


什么叫闭包?其实就是block(匿名函数),对于block这一概念,可能还是有一部分程序猿有着不小的疑惑,后期,我将写一篇关于block的使用的博客,好了,今天就先说一下Swift中的闭包.

闭包的格式: ((参数) -> 返回值类型)
var newPassValue : ((a : Int, b:Int) -> Int)

//第一种闭包表达式的写法
newPassValue = {(a : Int, b:Int) -> Int in
    
    return a > b ? a : b

}

//第二种闭包表达式的写法 苹果推荐的写法
newPassValue = { (a , b) -> Int in

    return a > b ? a : b

}

//第三种写法
newPassValue = {

    $0 > $1 ? $0 : $1

}

//第四种方法
newPassValue = { (a ,b) in
    
    return a > b ? a : b

}

//第五种方法
newPassValue = { (a ,b) in
    
  a > b ? a : b
    
}


各位看官喜欢的话,就点个喜欢吧,不求打赏,只求喜欢.

你可能感兴趣的:(华山论剑之Swift初体验(二))