1 import Foundation 2 3 // MARK: - ?和!的区别 4 // ?代表可选类型,实质上是枚举类型,里面有None和Some两种类型,其实nil相当于OPtional.None,如果非nil相当于OPtional.Some 5 // !强制解包 6 //var number : Int? // 此时解包会崩溃 7 var number : Int? = 8 // 此时解包不会崩溃 8 9 // 如果对没值(nil)的变量进行强制解包的情况下会造成崩溃 10 var number1 = number! 11 print(number1) 12 13 // 可选绑定,不用强制解包 14 if var number2 = number { 15 print(number2) 16 } 17 18 // !隐式解析可选类型:有值,没值(nil) 19 // 如果!强行解析没值的变量,也会造成崩溃 20 //var intNumber : Int! // 此时解包会崩溃 21 var intNumber : Int! = 6 // 此时解包不会崩溃 22 var intNumber1 = intNumber 23 print(intNumber1) 24 25 // 可选绑定 26 if var intNumber2 = intNumber { 27 print(intNumber2) 28 } 29 30 31 // MARK: - 结构体 32 // 1.声明一个结构体 33 struct Rect { 34 // 声明结构体变量的属性(存储属性) 35 var x : Float 36 var y : Float 37 var width : Float 38 var height : Float 39 40 // 声明结构体属性, 要使用static 41 static var description : String? 42 43 // 声明一个计算属性(是用来专门计算结构体变量属性的setter和getter方法的,本身并没有存储功能) 44 var centerX : Float { 45 // set方法 46 set { 47 x = newValue 48 } 49 // get方法(必须要写) 50 get { 51 return x / 2 52 } 53 } 54 55 var centerY : Float { 56 // 可以不写set方法,只写get方法 57 get { 58 return y / 2 59 } 60 } 61 62 // 声明方法 63 // 声明一个结构体变量方法(相当于OC中的实例方法) 64 func frameInfor() { 65 print("x : (x), y : (y), width : (width), height : (height)") 66 } 67 68 // 声明一个结构体方法(相当于OC中的类方法),使用static修饰 69 static func inFor() { 70 print("这是结构体方法") 71 } 72 } 73 74 // 2.根据结构体去定义一个结构体变量 75 var frame = Rect(x: 10, y: 10, 100, height: 100) 76 77 // 3.访问结构体变量中的属性 78 // 注意:结构体变量的属性类型可以使用let去修饰,只不过访问的时候不能进行修改 79 frame.x = 20 80 print(frame.x) 81 82 // 4.访问结构体属性 83 Rect.description = "我是结构体属性" 84 print(Rect.description) 85 86 // 5.访问计算属性 87 frame.centerX = 200 // 这句话相当于在调用centerX的set方法 88 let value = frame.centerX // 这句话就相当于在调用centerX的get方法 89 print(value) 90 91 // 6.调用结构体变量方法 92 frame.frameInfor() 93 94 // 7.调用结构体方法 95 Rect.inFor() 96 97 98 // MARK: - 类(class) 99 class Person { 100 var name : String? 101 var age : Int? 102 103 // 构造初始化方法 104 init (name : String, age : Int) { 105 self.name = name 106 self.age = age 107 } 108 109 // 自定义初始化方式(可以只初始化一部分属性) 110 init (name : String) { 111 self.name = name 112 } 113 114 // 声明类属性 115 static var introduce : String? 116 117 // 计算属性 118 var value : Int { 119 set(a) { 120 age = a // 在写计算属性的时候,一定不能出现self.,否则会造成死循环 121 } 122 get { 123 return age! 124 } 125 } 126 127 // 声明一个类方法 128 // 1.在类方法前边加上static修饰【虽然是一个类方法,但是该方法在子类中不能进行重写】 129 static func sayHi() { 130 print(introduce) // 注意:在类方法中只能使用类属性,不能使用对象属性 131 } 132 // 2.在类方法前边加上class修饰【它是一个类方法,可以被子类重写】 133 class func sayHi1() { 134 print(introduce) 135 } 136 137 // 声明一个实例(对象)方法 138 func sayHi2() { 139 print("hello, 我是实例方法") 140 } 141 } 142 143 // 1.创建对象(此时应该和OC区分开来,实例对象,:后边跟的是类,要初始化对象一定要写初始化构造的方法) 144 var person1 : Person = Person(name : "卫庄", age : 20) 145 146 // 2.访问类中的属性(对象属性) 147 print(person1.name!) 148 149 // 3.访问类属性 150 Person.introduce = "我是盖聂" 151 print(Person.introduce) 152 153 // 4.访问计算属性 154 person1.value = 28 155 print(person1.value) 156 157 // 5.访问类方法 158 Person.sayHi() 159 Person.sayHi1() 160 161 // 6.访问实例方法 162 person1.sayHi2() 163 164 165 // MARK: - 定义一个子类Student,继承Person 166 // 在swift中不支持多继承 167 class Student : Person { 168 // 重写父类的方法 169 // 重写父类中的类方法(class修饰的可以重写,static修饰的不可以重写) 170 override class func sayHi1() { 171 print("我是子类Student类,重写了父类的类方法") 172 } 173 174 // 重写父类中的实例方法 175 override func sayHi2() { 176 print("我是子类Student类,重写了父类的对象方法") 177 } 178 } 179 180 // 初始化student对象 181 var student : Student = Student(name: "天明", age: 12) 182 183 // 调用类方法 184 Student.sayHi1() 185 186 // 调用使用方法 187 student.sayHi2() 188 189 190 // MARK: - 值类型和引用值类型的区别 191 /* 192 // 值类型 193 struct animal { 194 var name : String? 195 var age : Int? 196 197 init(name : String, age : Int) { 198 self.name = name 199 self.age = age 200 } 201 } 202 var dog = animal(name: "贝贝", age: 3) 203 var dog1 = dog // 此时将dog的数据拷贝给dog1 204 dog.name = "欢欢" 205 print("dog.name : (dog.name!), dog1.name : (dog1.name!)") 206 */ 207 208 // 引用值类型 209 class animal { 210 var name : String? 211 var age : Int? 212 213 init(name : String, age : Int) { 214 self.name = name 215 self.age = age 216 } 217 } 218 var dog = animal(name: "贝贝", age: 3) 219 var dog1 = dog 220 dog.name = "欢欢" 221 print("dog.name : (dog.name!), dog1.name : (dog1.name!)") 222 223 224 // MARK: - 协议(protocol) 225 // 当swift中声明协议的时候,协议里有可选方法需要使用@objc关键字修饰 226 @objc protocol MarrayDelegate { 227 func cook() // 做饭 228 func wash() // 洗衣服 229 optional func hitDoudou() // 打豆豆 230 } 231 232 protocol DivorceDelegate { 233 func diviseMoney() // 分割财产 234 } 235 236 // 如果一个类要遵循协议的时候,如果这个类有父类要在:后先写父类,然后用,隔开,后面跟着协议 237 class Man: Person, MarrayDelegate, DivorceDelegate { 238 @objc func cook() { 239 print("我要做饭了") 240 } 241 242 @objc func wash() { 243 print("我要洗衣服了") 244 } 245 246 func diviseMoney() { 247 print("分财产") 248 } 249 } 250 251 // 创建一个男人 252 let man = Man(name: "韦小宝", age: 22) 253 man.cook() 254 man.wash() 255 man.diviseMoney() 256 257 258 // MARK: - 扩展(Extension) 259 // 1.扩展协议中的相关方法 260 extension Man { 261 @objc func hitDoudou() { 262 print("嘿嘿嘿") 263 } 264 } 265 man.hitDoudou() 266 267 // 2.扩展还可以扩展类方法(类似于OC中的Category)以及对象方法 268 extension Man { 269 // 扩展一个对象方法 270 func sing() { 271 print("唱一首歌") 272 } 273 274 // 扩展一个类方法 275 class func sleep() { 276 print("多喝水") 277 } 278 } 279 280 man.sing() 281 Man.sleep() 282 283 284 // MARK: - 闭包 285 // 求两个数的最大值 286 /* 287 在OC中使用Block实现 288 int (^myBlock)(int num1, int num2) = ^int (int num1, int num2) { 289 return num1 > num2 ? num1 : num2 290 } 291 */ 292 293 // 使用闭包 294 var myBlock : ((num1 : Int, num2 : Int) ->Int) 295 296 // 第一种使用方式 297 myBlock = { 298 (num1 : Int, num2 : Int) ->Int in // 切记不能忘记in 299 return num1 > num2 ? num1 : num2 300 } 301 302 // 第二种方式 303 myBlock = { 304 num1, num2 in 305 return num1 > num2 ? num1 : num2 306 } 307 308 // 第三种方式 309 myBlock = { 310 num1, num2 in 311 num1 > num2 ? num1 : num2 312 } 313 314 // 第四种方式 315 myBlock = { 316 $0 > $1 ? $0 : $1 317 } 318 319 // 第五种方式 320 myBlock = { 321 (num1, num2) ->Int in 322 return num1 > num2 ? num1 : num2 323 } 324 325 var max = myBlock(num1: 66, num2: 88) 326 print(max)