1、?和!
- 在swift中,可选类型(?)其根源是一个枚举型,里面有None和Some两种类型。其实所谓的nil就是Optional.None, 非nil就是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)
}
2、结构体
Swift的结构体对比OC来说,可以添加初始化方法、可以遵守代理协议等。
// MARK: - 结构体
// 1.声明一个结构体
struct Rect{
// 声明结构体变量的属性(存储属性)
var x:Float
var y:Float
var width:Float
var height:Float
// 声明结构体属性,要使用static
static var description:String?
// 声明一个计算属性(是用来专门计算结构体变量属性的setter方法和getter方法,其本身并没有存储功能)
var centerX:Float{
// setter方法
set{
x = newValue
}
// getter方法
get{
return x / 2
}
}
var centerY:Float{
get{
return y / 2
}
}
// 声明方法
// 声明一个结构体变量方法(相当于OC中的实例方法)
// 成员方法
func frameInfor(){
print("x:\(x),y:\(y),width:\(width),height:\(height)")
}
// 类方法在成员方法之前用static修饰
static func infor(){
print("这事结构体方法0")
}
}
// 根据结构体去定义一个结构体变量
var frame = Rect(x: 5, y: 5, width: 5, height: 5)
print(frame)
// 访问结构体变量中的属性
// 注意:结构体变量的属性类型可以使用let去修饰,只不过访问的时候不能对其值进行修改
frame.x = 10
print(frame.x)
// 访问结构体属性
Rect.description = "我是结构体属性"
print(Rect.description)
// 访问计算属性
frame.centerX = 200 // 这句话就相当于在调用centerX的setter方法
frame.x = frame.centerX // 这句话就相当于在调用centerX的getter方法
print(frame.x)
frame.frameInfor()
Rect.infor()
3、类
- 类是人们构建代码所用的一种通用且灵活的构造体。我们可以使用与结构体完全相同的语法规则来为类定义属性(常量、变量)和添加方法。
- 我们通过关键字class来定义类,并在一对大括号中定义它们的具体内容:
- class ClassName {
- 类的内部细节
- }
// MARK: - 类(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?
// 计算属性,不能出现self
var value:Int{
set(a){
age = a
}
get{
return age!
}
}
// 声明一个类方法
// 1.在类方法前边加上static修饰(虽然是一个类方法,但是该方法在子类中不能进行重写)
static func sayHi(){
print(introduce)// 在类方法中只能使用类属性,不能使用对象属性
}
// 2.在类方法前边加上class修饰(可以在子类中重写)
class func sayHello(){
print(introduce)
}
// 声明一个实例(对象)方法
func sayHei(){
print("hello,我是实例方法")
}
}
// 创建对象[要写初始化构造的方法]
var per:Person = Person(name: "Boy", age: 21)
print(per.name)
// 访问类属性
Person.introduce = "我是XXX"
per.value = 22
print(per.value)
print(Person.introduce)
// 访问类方法
Person.sayHi()
Person.sayHello()
// 访问实例方法
per.sayHei()
// 定义一个子类Student,继承Person
// 在Swift中不支持多继承
class Student:Person {
// 重写父类的方法
override class func sayHello() {
print("qweqwew")
}
// 重写父类中的实例方法
override func sayHei() {
print("我是子类的实例方法")
}
}
// 初始化Student对象
var student = Student(name: "张三", age: 54)
// 重写的类方法
Student.sayHello()
// 对象方法
student.sayHei()
- 值类型:该类型的每个实例持有数据的副本,并且该副本对于每个实例来说是独一无二的一份,比如结构体(struct)、枚举(enum)、元组(tuple)都是值类型。
- 引用类型:该类型的实例共享数据唯一的一份副本(在native层面说的话,就是该类型的每个实例都指向内存中的同一个地址),比如类(class)就是引用类型。
// MARK: - 值类型和引用类型的区别
struct a