Swift学习笔记-005结构体和类(疯狂swift讲义第二版)

1.定义类及类相关的一切

定义类的一般语法
[修饰符] class 类名{
//类的语句
}

定义结构体的一般语法
[修饰符] class 类名{
//结构体的语句
}

定义存储属性的一般语法
[修饰符] var | let 存储属性名:类型名=初始值

定义方法的一般语法
[修饰符] func 方法名(形参列表)->返回值类型{
//方法体语句
}

定义构造器的一般语法
[修饰符] init (形参列表){
//构造器语句
}

//定义一个类
class Person{
    var name:String=""
    var age:Int=0;
    func say(content:String){
        print("let me say somthing \(content)")
    }
}

var p1=Person()
var p2:Person
p2=Person()

p1.name="zhangsan"
p1.age=23
p1.say(content: "another things")

//定义一个结构体
struct Dog{
    var name:String!
    var age:Int!
    func say(content:String){
        print("let me say somthing \(content)")
    }
}

var d1:Dog
d1=Dog(name: "bighuang", age: 2)
print(d1.name)
d1.say(content: "wangwang")
d1.say(content: "wangwang")
var d2=Dog(name: "xiaobai", age: 2)
2.使用self
class Dog{
    var name:String!
    var age:Int!
    func jump(){
        print("we are jump")
    }
    func run(){
        self.jump()
        print("we are run")
    }
}

var d1=Dog()
d1.run()
3.使用结构体存储属性
struct FixedLengthRange{
    var start:Int
    let length:Int
}
var rg=FixedLengthRange(start: 2, length: 10)
rg.start=5
4.延迟存储属性(懒加载)
class Dept{
    var id:Int
    var info:String
    init(id:Int) {
        self.id=id
        //暂停2秒,模拟耗时操作
        Thread.sleep(forTimeInterval: 2)//swift4.0的线程睡眠表达语法
        self.info="模拟读取数据库"
    }
}

class User{
    var id:Int=0
    //var dept=Dept.init(id: 20)//不使用懒加载延迟两秒输出
    lazy var dept=Dept.init(id: 20)//使用懒加载后立即输出
    var nicks=[String]()

}
print("----------")
var user=User()
user.nicks.append("孙悟空")
user.nicks.append("猪八戒")
print(user.nicks)
5.定义计算属性(get,set)
class User{
    var first:String=""
    var last:String=""
    
    var fullName:String{
            get{
            return first+last
            }
            set{
            var names=newValue.components(separatedBy: "-")
            self.first=names[0]
            self.last=names[1]
            }
        }
    init(first:String,last:String){
        self.first=first
        self.last=last
    }
}

let s=User(first: "孙", last: "悟空")
print(s.fullName)
s.fullName="猪-八戒"
print(s.first)
print(s.last)

打印结果
孙悟空

八戒

6.方法

swift统一了函数和方法的语法格式,如果函数放在枚举、结构体、类以外定义就是函数,如果放在枚举、结构体、类之内定义就变成了方法

值类型的实例方法不能改变该实例的存储属性,如果需要让值类型的实例方法改变实例的存储属性,程序需要使用mutating将该方法声明为可变方法。

struct FKRect{
    var x:Int
    var y:Int
    var width:Int
    var height:Int
    
    mutating func moveByX(x:Int,y:Int){
        self.x=x
        self.y=y
    }
}

var rect = FKRect(x: 20, y: 12, width: 200, height: 300)
rect.moveByX(x: 100, y: 80)
print("\(rect.x)---\(rect.y )")

可变方法还可以对self直接赋值

enum Planet:Int {
    case Mercury=0,Venus,Earth,Mars,Jupiter,Saturn,Nepturn
    mutating func next(){
        if self.rawValue<8 && self.rawValue > -1 {
            self = Planet(rawValue: self.rawValue+1)!//对self直接赋值,使用期rawValue的下一个下标
        }
    }
    mutating func pre(){
        if self.rawValue<8 && self.rawValue > -1  {
            self = Planet(rawValue: self.rawValue-1)!
        }
    }
}

var pt = Planet.Venus
pt.next()
print(pt.rawValue)
pt.pre()
print(pt.rawValue)

打印结果
2
1

7.下标

下标的一般语法为:
subscript(形参列表)->下标返回值类型{
get{
//get部分执行体,该部分必须有返回值
}
set{
//set部分执行体,该部分不一定能有返回值
}
}
下标可以重载

struct FKRect{
    var x:Int
    var y:Int
    var width:Int
    var height:Int
    //定义一个下标
    subscript(idx:Int)->Int{
        //定义下标的get部分
        get{
            switch idx{
            case 0:
                return self.x
            case 1:
                return self.y
            case 2:
                return self.width
            case 3:
                return self.height
            default:
                print("unsupporting")
                return 0
            }
        }
        
        //定义下标的set部分
        set{//省略色set部分的形参名,直接使用程序提供的隐式形参名newValue
            switch idx{
                case 0:
                    self.x=newValue
                case 1:
                    self.y=newValue
                case 2:
                    self.width=newValue
                case 3:
                    self.height=newValue
                default:
                    print("unsupporting")
            }
        }
 
    }
}

var rect=FKRect(x: 20, y: 12, width: 200, height: 300)
rect[0]=40
rect[1]=67
print(rect)

打印结果
FKRect(x: 40, y: 67, width: 200, height: 300)

8.下标的重载
extension String{
    subscript(idx:Int)->String{
        get{
            if idx > -1 && idx < self.utf16.count{
                return(self as NSString).substring(with: NSMakeRange(idx, 1))
            }else{
                return""
            }
        }
        
        set{
            self=(self as NSString).replacingCharacters(in: NSMakeRange(idx, 1), with: newValue)
        }
    }
    subscript(start:Int,end:Int)->String{//形参个数不一样,进行了重载
        get{
            return ""
        }
        set{}
    }
    
}
9.可选链

为了能够让某种数据类型接受nil值(所有的swift类型默认不能接受nil值),需要将该类型包装成可选类型,可以有两种方法:
1、在原有类型后面添加?后缀,这种可选类型必须强制解析(使用感叹号!)才可以获取被包装的值
2、在原有类型后面加!后缀,这种可选类型可由swift隐式解析被包装的值

class Customer{
    var name=""
    var emp:Employee?
    init(name:String){
        self.name=name
    }
}

class Employee{
    var name="zhansan"
    var title="manager"
    var company:Company!
    init(name:String,title:String) {
        self.name=name
        self.title=title
    }
    func info(){
        print("the employee is \(name) and \(title)")
    }
}

class Company{
    var name="fengraytech"
    var addr="huilongguan"
    init(name:String,addr:String) {
        self.name=name
        self.addr=addr
    }
}

var c1=Customer(name:"孙悟空")
var emp=Employee(name:"白骨精",title:"销售")
c1.emp=emp
emp.company=Company(name:"烽火科技",addr:"北京长安街")
print("my customer\(c1.name) is from \(c1.emp!.company.name)")//这里emp后面使用了强制解析的符号感叹号!

//下面使用可选链的方式来引用company的name
var c2=Customer(name:"唐僧")
c2.emp=Employee(name:"白骨精",title:"销售")
print("my customer\(c2.name) is from \(c2.emp?.company?.name)")//这里emp后面使用了可选符号?,因为没有实例化company,因此要返回一个nil值

打印结果
my customer孙悟空 is from 烽火科技
my customer唐僧 is from nil

10.使用可选链调用方法
class Employee{
    var name="zhansan"
    var title="manager"
    init(name:String,title:String) {
        self.name=name
        self.title=title
    }
    func info(){
        print("the employee is \(name) and \(title)")
    }
    func findEmp(empName:String)->Employee!{//使用隐式解析
        for emp in employees{
            if emp.name==empName{
                return emp
            }
        }
        return nil
    }
}

let employees = [
    Employee(name: "白骨精", title: "销售客服"),
    Employee(name: "蜘蛛精", title: "售后客服"),
    Employee(name: "白龙马", title: "普通客服"),
    Employee(name: "牛魔王", title: "销售主管")
]


var e1=Employee(name: "zhangsan", title: "manger")
e1.findEmp(empName: "白龙马")?.info()//使用了可选链的方式调用findEmp方法

打印结果
the employee is 白龙马 and 普通客服

11.使用可选链调用下标方法
class Employee{
    var name="zhansan"
    var title="manager"
    init(name:String,title:String) {
        self.name=name
        self.title=title
    }
    func info(){
        print("the employee is \(name) and \(title)")
    }
    func findEmp(empName:String)->Employee!{//使用隐式解析
        for emp in employees{
            if emp.name==empName{
                return emp
            }
        }
        return nil
    }
}

let employees = [
    Employee(name: "白骨精", title: "销售客服"),
    Employee(name: "蜘蛛精", title: "售后客服"),
    Employee(name: "白龙马", title: "普通客服"),
    Employee(name: "牛魔王", title: "销售主管")
]

var dict = [Int:Employee]()
dict[1] = Employee(name: "白骨精", title: "销售客服")
dict[2] = Employee(name: "白龙马", title: "普通客服")

dict[1]?.findEmp(empName: "白骨精")?.info()//使用可选链

打印结果
the employee is 白骨精 and 销售客服

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值