/——————— 1 可选类型 —————–/
// ?表示可选类型 该变量可以正常赋值 也可以为nil
//如果一个对象用?修饰 就表示这是一个可选类型 其值是可以为空的 但是如果我们想使用它真正的值的时候 就需要在该对象的后面加上一个!表示解包 去除真实值使用
//虽然可选类型可以为nil 但是如果为nil 的时候去使用 仍然会崩溃
var a:Int? = 8
var b = a!
print(b)
/——————— 2 闭包 ——————–/
//闭包:封闭的代码块 类似于blcok
/*语法格式
{ (参数列表) 返回值类型 in
闭包的代码块
}
*/
//函数类型 int maxValue (int a, int b)
//int maxValue (int a int b)
//由两个int类型的参数,一个返回值为int的函数类型
//求两个数的最大值
var maxValue:((a:Int,b:Int)->Int)
maxValue =
{(a:Int,b:Int) ->Int in
return a > b ? a : b
}
print(maxValue(a: 5, b: 4))
/——————— 3 结构体 —————– /
//声明是一个协议
//如果一个协议里面有可选方法 那么就需要在该协议前面加上@objc 如果没有 就不用加
//swift中结构体只能遵守必须执行的协议,如果一个协议中有可选方法,只能用类去实现
protocol proMethodDelegate{
//默认是必须执行的
func proMethod()->String
//可选方法
// optional func proOptionalMethod()->String
}
//定义一个点的结构体
struct Point {
var x = 0
var y = 0
}
//定义一个size的结构体
struct Size {
var width = 0
var height = 0
}
struct Rect:proMethodDelegate {
// 1 属性
var Origin = Point()
var size = Size()
//构造函数(就是oc里面的初始化方法)
// 2 为该结构体创建一个构造函数
init(x:Int,y:Int,w:Int,h:Int)
{
self.Origin.x = x
self.Origin.y = y
self.size.width = w
self.size.height = h
print("创建一个rect对象")
}
// 3 在rect结构体里面,定义一个静态方法(和oc中的类方法一样),要用static修饰
static func classMathed()
{
print("这是一个结构体的类方法")
}
// 4 结构体可以实现协议方法
func proMethod() -> String {
return "这是一个结构体实现的协议方法"
}
}
//结构体的使用
var r:Rect = Rect(x: 10, y: 10, w: 100, h: 100)
print(r)
//结构体调用结构体的类方法
Rect.classMathed()
//结构体调用协议方法
print(r.proMethod())
print(“**********类和对象********”)
//swift中也是单继承 但并不是所有的类都必须要继承NSObject
//没有继承的类 ,表示是基类
class Person {
/*
在swift中属性有三种
1 储存属性:就是用来保存某个值使用的 很类似于OC中的实例变量
2 计算属性:专门用来处理属性数据的运算
3 类属性:用类直接调用的属性
*/
//1 储存属性:就是用来保存某个值使用的 很类似于OC中的实例变量
var name:String?
var age = 20
var chinese = 0
var math = 0
var english = 0
//延迟储存属性(懒加载)
lazy var f:file = file()
// 2 计算属性:专门用来处理属性数据的运算
//计算属性一定是变量
//计算属性一定还会重写set或者get方法
var sum:Int{
get{
return chinese+math+english
}
set(newValue)
{
print(“newValue的值为(newValue)”)
}
}
// 3 类属性:用类直接调用的属性, 类属性只能是计算属性
class var cVar:String{
get{
return “这是一个人的类属性”
}
}
/********************方法*********************/
//swift中所有的变量都必须赋初始值 如果在类里面声明属性的时候没有初始值 那么在构造函数中必须初始化 如果有多个初始化方法 呢么每个初始化方法都要对没有赋值的属性进行赋值
//默认的初始化方法
init()
{
self.name = ""
print("这是人类默认的初始化方法")
}
//方法的重载:OC中没有这个概念,借鉴的JAVA和C++里面的概念
//方法名一样 只是参数不一样 (参数名和参数个数)
//自定义构造函数
init(name:String,age:Int)
{
//在swift中不用写return
self.name = name
self.age = age
}
//便利构造器(实质上还是调用正常的构造函数) 就是在正常的构造函数前面加了一个convenience关键字
convenience init(Name:String,Age:Int)
{
self.init(name:Name,age:Age)
}
//析构函数,类似于OC里面的delloc方法
deinit{
print("人死了")
}
func sleep(){
print("这是一个人在睡觉")
}
}
//文件类
class file {
init()
{
print(“这是一个很大的文件”)
}
}
//创建person类对象
var p = Person()
p.chinese = 80
p.math = 90
p.english = 60
print(p.sum)
p.sum = 100
//便利构造器的使用
var pi = Person(Name: “xiaoA”, Age: 27)
print(pi.name)
func test(){
_ = Person()
}
print(“*****函数调用前**********”)
test()
print(“*****函数调用后**********”)
/*************面向对象特性*********/
//继承
class Man:Person{
//override;重写父类方法的关键字 子类的初始化方法会先调用super指针为其创建一个父类对象
override init(){
super.init()
print(“这是一个男人的初始化方法”)
}
//子类重写父类方法 优先调用子类里面的方法
override func sleep() {
print(“这是一个男人在睡觉”)
}
func eat(){
print(“这是一个男人在吃饭”)
}
}
var m = Man()
m.sleep()
/*************多态***************/
//为什么说OC是一门动态运行时语言?
//多态:父类指针指向子类对象
//因为子类里面可以添加自己的方法 相比于父类来说 子类里面的方法和属性会更丰富 所以父类的指针能指向的范围比较小 而子类指针的范围比较大 一个小范围的指针 指向大得范围 肯定不会溢出范围 只是有些范围指不到而已 但是如果大范围的指针 指向小的区域 就有可能 指向小区域以外的东西 从而找不到想要的内容 引起程序崩溃 所以子类指针指向父类对象 在oc语法上没有错误(swift直接语法报错) 但是有以上隐患 所以我们只把多态看做是父类指针指向子类对象
class Woman: Person {
override func sleep() {
print(“这是一个女人在睡觉”)
}
func eat(){
print(“这是一个女人在吃饭”)
}
}
//Woman对象
var w = Woman()
w.sleep()
w.eat()
print(“*******************”)
//父类指针指向子类对象
var p4:Person = Woman()
p4.sleep()
//子类指针指向父类对象
//var p5:Woman = Person()
//************* 延展 *******
//在延展里面可以向一个类里面添加 实例变量 属性 方法
//在swift中只能添加方法
extension Woman{
func wash(){
print(“这是一个女人在洗衣服”)
}
}