Swift中的结构体
Swift的结构体对比OC来说,可以添加初始化方法、可以遵守代理协议等,同时:Swift的Bool类型的变量也是一个结构体,所以只能选择true和false。
Swift中声明结构体的格式:
struct(关键字) + 结构体名字 {
结构体内部实现代码
}
上面是结构体声明的基本格式,不过结构体中可以不仅仅可以设置存储属性,还可以设置计算属性,除此之外还可以在其中声明结构体本身的属性
在Swift与OC的改变之处:
第一个变化就表现为在结构体内可以实现初始化的方法,并且在实现初始化方法的时候需要添加func标识
第二个变化就表现为在结构体中可以定义结构体的方法(函数变量)--------性质和类的方法一致【需要在前面使用static标识 在Swift中static并不表示在静态区声明一个变量【代表结构体方法】】
// 主要是用来存值的
struct Rect {
// 存储属性 :目的是用来存值的
var x : Float
var y : Float
var width : Float
var height : Float
// 计算属性 : 专门计算存储属性的一个变量的
var centerX : Float {
// 实现计算属性的get,set方法
// Swift中不能之定义setter方法,如果需要setter方法则需要实现getter方法之后在去实现setter
get{
return x + width / 2
}
// Swift 里面set不能单独实现,必须要有get方法
set{
//newValue 新的值
centerX = newValue
}
// center是计算属性 : 里面存放一些set,get方法
// 声明实现了getset,及实例变量
}
var centerY :Float {
get{
return y + height/2
}
set{
centerY = newValue
}
}
// 声明一个结构体的属性
static var name : Float {
get {
return 100
}
}
// 结构体第一个变化: —— 可以实现初始化方法
// 在实现初始化方法的时候,不需要添加func标识
init(x : Float, y : Float, width : Float, height : Float)
{
self.x = x
self.y = y
self.width = width
self.height = height
}
// 结构体里面的函数
// 在结构体里面的函数名的前面加一个 mutating,表示可以函数里面修改结构体参数的值如果不加则在函数内部不可以修改
mutating func sayHello() {
self.x = 120;
print("☀️????")
}
// 定义一个结构体方法(函数) —————— 性质和类方法一致
// 使用static 标识 在Swift中的static并不表示在静态区声明一个变量【代表结构体方法】
static func sayNiHao() {
print("windsSunShine")
}
}
// 使用一个结构体
var newRect = Rect(x: 1.0, y: 1.0, width: 100, height: 100)
// 调用结构体里面的函数
newRect.sayHello()
// 只能结构体本身调用 相应的方法
Rect.sayNiHao()
print("newRect.x = \(newRect.x),newRect.y = \(newRect.y),\n newRect.width = \(newRect.width),\n newRect.hight = \(newRect.height)")
Swift中的类到是变化不太大,声明类的格式为:
class(关键字) + 类名 : 父类 {
类里面的代码实现
}
在Swift中不管是结构体还是类他都有static修饰的方法,在结构体中表示结构体的方法,只能结构体本身去调用,在类中表示类的函数变量并且在Swift的类中有两种声明函数变量的方式:第一种就是用static但是用static修饰的函数变量不能够被子类所重写的,而用class修饰的函数变量可以被重写
具体的类的声明代码及函数变量的声明及使用如下:
class Person {
var name : String?
var age : Int?
// 使用static修饰表示是一个类属型
static var gender : String?
// hobby是私有属性
private var hobby : String?
init(name : String, age : Int) {
self.name = name
self.age = age
}
// 实例方法(对象的)
func sayHi() {
print("你好 我是实例方法")
}
// 声明一个类函数(OC中的方法)
static func sayHello() {
// 使用static修饰的方法子类是不能重写的
// 只能调用类属型, 用Static修饰的属性
// 调用类的属性
self.gender = "hh"
// 调用类的方法
self.sayNiHao()
// 调用本身的实例函数
let person = Person(name: "Sun", age: 500)
person.sayHi()
}
// 声明一个类的函数
class func sayNiHao() {
// 使用class修饰的类函数 是能够被子类重写的
}
}
当我们在使用我们定义的类的时候可以使用 : 类名+ ()的形式
var person = Person(name: "windsSunShine", age: 18)
person.hobby = "ReadBook"
print("My name is\(person.name),my age is\(person.age), my hobby is\(person.hobby)")
Person.sayHello()
Person.sayNiHao()
类的继承:
声明一个类继承与父类的方式和OC中的一样 ,如果在子类中有需要重写的父类的方法,则需要加上 override 标识
代码如下:
class Student: Person {
// 子类重写父类方法的时候要加上 override标识
override func sayHi() {
// 表示继承父类的方法并添加新的功能
super.sayHi()
}
}
有了类肯定要使用代理的方法用来处理一些回调之类的不过再Swift中使用代理的方法和OC中的有所不同,
定义代理的格式:
protocol (关键字) myDeledate(协议名) {
协议方法 【协议方法前面如果不加修饰词的话是默认必须实现的】
}
protocol myDelegate {
//必须实现的 协议中的方法
func hehe()
// 协议中的类方法
// static func meishayong()
}
这样代理中并不是都是必须实现的方法如果想要代理中存在不是必须实现的方法需要加上关键字 @objc
如下:
// 如果想声明一个有可选实现方法的代理协议,需要使用@objc 在protocol之前去标识一下,在协议里面的可选实现函数前,加optional 去表示这个函数是可选实现的
// 加上@objc 表示协议中有可选实现的代理方法
@objc protocol newDelegate {
func haha()
optional func winds() // 表示为可选实现的方法
}
在类继承协议的时候:
需要注意:
如果一个类有父类,则类名后面一定要是父类然后才是代理协议
如果遵守的协议里面有必须实现的函数没有实现的话会报红,不能运行
如果一个类遵守吧了一个含有可选实现的函数协议,则在实现这个协议方法之前需呀添加@objc去标识这个方法
在遵循代理方法的后面添加逗号
代码如下:
class Teacher : Person, myDelegate {
func hehe() {
print("????????")
}
// 添加@objc
@objc func haha() {
}
}
定义对象调用协议中的方法:
var teacher = Teacher(name: "?", age: 1)
teacher.hehe()
其实不只是在类中这样可以继承协议,在Swift的结构体中也能继承新的协议:
不过再结构体继承协议有一点需尤为注意:
结构体也可以遵循协议【协议里面的方法都是必须实现的,没有可选实现的】后面跟的是冒号 ,但是不能遵循包含可选方法的协议
protocol myDelegate {
//必须实现的 协议中的方法
func hehe()
// 协议中的类方法
// static func meishayong()
}
struct Point : myDelegate {
func hehe() {
}
}
类的拓展:
我们在Swift中也可以給类拓展新的方法,但是只能够拓展新的方法不能够拓展出新的属性
// 给Teacher类拓展新的方法
extension Teacher {
// 只能拓展出的新方法 不能拓展出新的属性
func newFunc() {
print("我是新出现的方法")
}
}
除此之外:拓展还可以让一个类去遵循新的代理协议
extension Teacher : newDelegate {
func heh() {
}
}
在类中可以拓展,在结构体中也能够拓展,
拓展可以让结构体拓展一个新的协议 遵循协议 ,也可以为结构体拓展一个新的方法
//拓展让结构体拓展一个新的协议 遵循协议
extension Rect :myDelegate
{
func hehe() {
}
}
// 为结构体拓展新的方法
extension Rect {
func newFunc() {
print("????新的结构体方法???????")
}
}
var rect = Rect(x: 100, y: 100, width: 100, height: 100)
rect.newFunc()
但是拓展的方法只能在拓展之后调用,注意一个时间先后的问题:
// 在拓展的下面能够调用拓展里面的方法
teacher1.newFunc()
在OC中我们经常使用block实现函数的回调啦,传值啦~其实在Swift中使用最多的还是闭包:
举个例子: 我们要求两个数的最大值,那么我们可以这样使用闭包
// 求两个Int类型参数的最大值
func text1(a : Int, b : Int) -> Int {
return a > b ? a : b
}
其实闭包的表达是我们就可以这样写出来:
// 闭包表达式
var newMaxValue:((a: Int, b : Int) ->Int)
下面简单的写几种实现闭包的方式:
// 实现闭包的方式
// 第一种实现方式
newMaxValue = {
(a:Int,b:Int) -> Int in // in是实现闭包的关键字
return a > b ? a:b
}
print(newMaxValue(a: 100, b: 11))
// 第二种实现方式
newMaxValue = {
// 省去参数类型, 返回值类型
a, b in
return a > b ? a:b
}
// 调用
print(newMaxValue(a: 100, b: 11))
// 第三种实现方式
newMaxValue = {
a,b in
a > b ? a : b
}
// 第四种实现方式
newMaxValue = {
// 去第0个参数,取第二个参数,在相互比较
$0 > $1 ? $0 : $1
}
// ?推荐使用的方法 第五种实现方法
newMaxValue = {
(a,b) -> Int in
return a > b ? a : b
}
其实闭包的应用有好多就单单一个对数组的排序我们就用到了
// 系统提供的对数组排序的闭包
var array = [1,3,5,6,7,83,2]
array.sortInPlace { (a,b) -> Bool in
return a > b
}
添加:Swift中的关键字:
欢迎转载,请注明转载和原文出处:http://www.cnblogs.com/windsSunShine/p/4992187.html