// 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)
}