swift学习笔记之类和对象

// ---------------类和对象----------------
//1类的组成 
// 类==属性+下属脚本+方法
//属性:它将值和特定的类关联
//下属脚本:访问对象,集合的快捷方式
//方法:实现某一特定的功能,类似于函数

//2类的创建 class 类名 {

//}

//3实例化对象
//var/let 对象名=类名()   ()不能少


//----------------属性--------------
//在OC中,属性使用关键字@property进行声明的内容,在swift中,属性可特定类,结构,或枚举关联,
//属性一般分为存储属性,计算属性,和类型属性

//1存储属性
//存储特定类的一个常量或者变量,根据数据是否可变可以分为常量存储属性和变量存储属性

//     1>定义存储属性
// let 常量存储属性变量名:数据类型=初始值
// var 变量存储属性变量名:数据类型=初始值

class newClass {
    let value1=20    //初始值不可少
    var value2:Int=0 //初始值不可少
}

//     2>访问存储属性
//       点语法.    1.访问变量  2.修改变量

let newclass=newClass()
print( "\(newclass.value1)")
newclass.value2=100


//    3延迟存储属性
//     若果只有在第一次调用存储属性时才确定初始值,这时需要延迟存储属性 lazy
//    lazy var 属性名:数据类型=初始内容
// 注意:@1延迟存储属性中的初始内容是不可以省略的,数据类型可以省略的,因为类型推断
//      @2定义延迟属性必须用var f否则会报错


class DataImportor {
    var fileName=123456
}

class DataManager {
    lazy var importor=DataImportor()
    var data:String = ""
}

let manager = DataManager()
manager.data += "more data"
print(manager.data)
print(manager.importor.fileName) //没调用 manager.importor.fileName 时,importor这个属性不会被创建



//2.计算属性
//计算属性不存储值,只是提供了一个getter和setter 来分别获取值和其他属性的值
//getter一般定义方法 get {
//   .....
//   return 某个值
//}

//setter一般定义方法 set(参数名称) {
//   .....
//   属性值=某一值
//}

//计算属性同时包含getter 和setter

//var 属性名:数据类型 {
// get {
//   .....
//   return 某个值
//  }
// set(参数名称) {
//   .....
//   属性值=某一值
//  }

//}

class WalletClass {
    var dollor=0.0  //美元
    var cal:Double {
        get{              //顶替getter
        let RMB=dollor*6.2 //注意  @1必须let  @2//必须指定数据类型  @3 set()的参数的数据类型必须和返回值的数据类型相同
            return RMB    //返回以人民币为单位的金额
        }
        set(RMB){        //定义setter
        dollor=RMB/6.2    //返回以美元为单位的金额
        }
    }
}

var mywallet=WalletClass()
mywallet.cal=20
print(mywallet.cal)
print(mywallet.dollor)


//注意 @4 没有定义参数的名称 可以使用 默认名称newValue
class WalletClass1 {
    var money=0.0  //美元
    var cal:Double {
        get{
            let RMB=money*6.2 //
            return RMB
        }
        set {
            money=newValue/6.2    //注意 @5 定义参数名后不能使用默认参数名 如果有了默认的newValue了,在set 加参数名同样报错
        }
    }
}

var mywallet1=WalletClass1()
mywallet1.cal=200
print(mywallet1.cal)
print(mywallet1.money)


//注意@6  setter 和getter的省略
//在计算属性中,如果只有一个getter 则只成为只读计算属性.只读属性可以返回一个值,但不能设新的值

class  personName {
    var name :String=""
    var returnName:String {  //可以省略get

        if(name.isEmpty){
        return "NULL"
        }
        else {
        return name
        }

    }
}

var person = personName()
print(person.name)
person.name="TOM"
print(person.name)


//3.类型属性
//类型属性就是不需要对类进行实例化就可以使用的属性.他需要关键字class进行定义
//class var 类型属性名:数据类型 {
//....
// 返回一个值
//}

class Cls {
    var count=100
    class var newValue:String {
        return "hello"
       // return count
    }
}

print(Cls.newValue)//hello

for index in Cls.newValue.characters {
print(index)

}

//注意点 @1 let 不能声明类型属性  @2存储属性 类型属性不能使用存储属性 
//@3,对象不能访问类型属性,类型属性,只能使用类访问,不可以使用对象进行访问
var cls=Cls()
//cls.newValue 错误

//注意 @4 类型属性和存储属性一样,不仅可以访问,还可以修改

var value:Int=0
class newClass1 {
    class  var count:Int {
        get{
        let newValue=value
        return newValue
        }
        set {
        value=newValue
        }
    }
}

print("修改前:\(newClass1.count)")
newClass1.count=200
print("修改后:\(newClass1.count)")


//属性监视器
//属性监视器来监控和相应属性值的变化,每次属性被设置值的时候,都会调用 属性监视器,哪怕新的值和原先的值相同,属性监视器,由willSet 和 didSet 组成 
//定义方式 
/**
*  var 属性名:数据类型:=初始值 {
willSet(参数名) {  //在设置新的值之前被调用,他会将新的属性值作为固定参数传入
..
}
didSet(参数名) {  //在新的值设置之后调用,会将旧的属性值作为参数传入,可以为该参数名或者默认的参数名oldValue

}

}

*/
print("--------------测试属性监控器------------")
class StepCounter {
    var totalSteps:Int=0 {  //千万前面不能加lazy
        willSet(newTotalSteps) {
        print("新的值:\(newTotalSteps)")
        }

        didSet(old) {
            if (totalSteps > old) {
                print("与原来比增减了\(totalSteps - old)个值")
        }

    }

    }
}

let stepCounter = StepCounter()
stepCounter.totalSteps=0
stepCounter.totalSteps=200
stepCounter.totalSteps=400
stepCounter.totalSteps=800

//需要注意的事项  
// @1 当willSet()不指定 参数名时 可以使用newValue didSet()不指定参数名的时候,可以使用oldValue代替
// @2默认参数不可以交换使用 ,也就是willSet 里的newValue 和didSet里的oldValue不可以交换使用
// @3延迟属性不能属性监控器   var totalSteps:Int=0 前面加个lazy 就不行
// @4分开使用willSet 和didSet. 也就是willSet 和didSet不一定成对出现 ,可以只是用willSet或者didSet




//--------------------------方法-----------------------
//1实例方法(有对象调用)
// 1> 不参数的实例方法
// 2>带一个参数的实例方法
// 3>带多个参数的实例方法
class ClassA {
    var str="hello"
    func printHello(){
    print(str)
    }
}

let clsA=ClassA()
clsA.printHello()


class AddClass {
    var count:Int=0
    func add(amount1:Int,amount2:Int){
     count=amount1+amount2
        print(count)
    }
}
let counter=AddClass()
counter.add(100, amount2: 200)

//2类型方法 由类调用
//  1>无参数的类方法
//  2>一个参数的类方法
//  3>多个参数的类方法

class MutiplyClass {

    var number:Int=0//存储属性

   class func Mutiply(amount1:Int,amount2:Int){
    var count:Int=0
        count=amount1*amount2
        print(count)
  // print(number)  @1不可以使用存储属性
    }
}
//注意事项
//@1不可以使用存储属性
//@2类调用
//@3外部参数名,和实例方法相同,swift 默认给类型的第一个参数一个局部参数名称,默认同时给第二个和后续的参数一个局部参数名称和外部参数名称,调用时不要忘记外部参数名


//3.存储属性,局部变量和全局变量的区别
//存储属性定义在类中,
//局部变量定义在函数,方法或闭包内部,
//全局变量定义在函数,方法,闭包或者任何类型之外定义的变量


//4局部变量和存储属性同名解决的方法 self

class ClassB {
    var count:Int=100
    func printCount() {
   self.count=50
    print(self.count)
    }
}
let clsB=ClassB()
clsB.printCount()

//--------------------------------------下属脚本----------------------------
//下属脚本是访问对象,集合或者序列的快捷方式.开发者不需要调用实例特定的赋值和访问方法,就可以直接访问所需要的数值,
//例如利用数组的下标去访问和修改数组的某个元素
//1定义下标脚本

/**
*  subscript(参数1:数据类型,参数2:数据类型,参数3:数据类型)->返回值数据类型 {

get {
//返回与参数类型匹配的类型的值
}
set(参数名称){
//执行赋值操作
}

}
*/

class ClassC {
    var english:Int=0
    var chinese:Int=0
    var math:Int=0

    subscript(index:Int)->Int {
        get {

        switch index {
        case 0:
            return english
        case 1:
            return chinese
        case 2:
            return math
        default:
            return 0
        }

      }
        set{
            english=newValue
            chinese=newValue
            math=newValue

        }
    }
}

//2调用下属脚本

var clsC=ClassC()

var i:Int=0
var sum:Int=0
for i=0;i<3;i++ {
   sum += clsC[i]

}
print(sum)

//修改属性的值
clsC[0]=100
clsC[1]=200
clsC[2]=300


for i=0;i<3;i++ {
    sum += clsC[i]

}
print(sum)

//下属脚本和计算属性一样设置为只读或者致谢
//只读
class Sorce {
    var english:Int=130
    var chinese:Int=50
    var math:Int=90

    subscript(index:Int)->Int {
        get {

            switch index {
            case 0:
                return english
            case 1:
                return chinese
            case 2:
                return math
            default:
                return 0
            }

        }

    }
}

var myScore=Sorce()

for j in 0...2 {

    print(myScore[j])
}

//具有多个参数的下标脚本,一般用在多维数组中

class mutiArrayClass {

    var rows:Int=0
    var columns=0
    var grid=[Double]()

    init(rows:Int,columns:Int) {

        self.rows = rows
        self.columns = columns
        grid=Array(count: rows*columns, repeatedValue: 0.0)
    }
    func indexIsValid(row:Int,column:Int)->Bool {

        return row >= 0 && row < rows && column >= 0 && column < columns
    }

    subscript(row:Int,column:Int)->Double {

        get {

            assert(indexIsValid(row, column: column), "index out of range")
            return grid[(row*columns)+column]
        }
        set {

        assert(indexIsValid(row, column: column), "index out of range")
            return grid[(row*columns)+column]=newValue


        }
    }
}
var mutiArr=mutiArrayClass(rows: 2, columns: 2)
print("没有赋值前")
print(mutiArr[0,0])
print(mutiArr[0,1])
print(mutiArr[1,0])
print(mutiArr[1,1])

mutiArr[0,0]=1.4
mutiArr[0,1]=53.234
mutiArr[1,0]=42.55
mutiArr[1,1]=1000.345532

print("赋值后")
print(mutiArr[0,0])
print(mutiArr[0,1])
print(mutiArr[1,0])
print(mutiArr[1,1])

//下属脚本除了访问对象以及对象的属性外,还可以实现一些自定义的功能
//一下代码实现的功能计算下标值和10的乘积

class ClassD {
    var count1:Int=10
    subscript(index:Int)->Int {

        get{
        let count=index*count1
            return count

        }
        set {
        count1 = newValue
        }

    }
}

let clsD=ClassD()
print(clsD.count1)
print(clsD[6])

//-----------------------------可选连接----------------------
//在或者其他的类型,声明的属性或者变量/常量都不可以为空,为了解决这样的问题,swift 就有了可选类型
//可选连链接就是为了使用可选类型,可选链接可以判断请求或者调用的目标(属性,方法,下标脚本等)是否为空 ,如果目标有值,就调用,否则,分返回nil
//swift的可选链接与OC的消息为空类似,但是swift 可以使用在任意的类型中,并且失败与否可以被检测到


//1,可选链接的实现方式
/**
*  属性名?  //属性的可选链接
   下标脚本? //下标脚本的可选链接

   方法名? //方法的可选链接



对象的可选链接的调用方式
对象.可选连接

*/

//2定义属性的可选链接

class Residence {
    class var numberOfRooms :Int? {
    return 100
    }
    var number:Int?
}

let reClass=Residence()

if let a=Residence.numberOfRooms {
  print("目标值")
}
else {
print("目标值为空")
}

if let num=reClass.number {
    print("目标值")
}
else {
    print("目标值为空")
}

//3通过可选链接调用属性,下标脚本和方法

//   1>通过可选链接调用属性的语法形式
//    可选链接.属性名


class  Person {
    var residence:ResidenceA?//nil
}
class ResidenceA {
    var numberOfRooms = 10
    subscript(i:Int)->Int {
    return i
    }
    func printRoomNumber() {
    print("the number of room is \(numberOfRooms)")
    }
}

let tom = Person()
if let roomCount = tom.residence?.numberOfRooms {//通过可选链接调用属性
    print("tom的房子有\(roomCount)个房间")

} else {
print("无法检索房间数")
}

let john = Person()
let johnResidence=ResidenceA()
john.residence=johnResidence //赋值
if let roomCount = john.residence?.numberOfRooms {//通过可选链接调用属性
    print("jhon的房子有\(roomCount)个房间")

} else {
    print("无法检索房间数")
}

//通过可选链接调用下标脚本

let Lily=Person()

if let firstRoomName = Lily.residence?[5]{
    print("Lily的房子有\(firstRoomName)个房间")

} else {
    print("无法检索房间数")
}

if let firstRoomName = john.residence?[5]{
    print("john的房子有\(firstRoomName)个房间")

} else {
    print("无法检索房间数")
}

//通过可选链接调用方法

let LinMeimei = Person()//

if let f: ()=LinMeimei.residence?.printRoomNumber() {
print("打印房间数")
} else {

    print("无法打印房间数")
}

//有值
if let f: ()=john.residence?.printRoomNumber() {
    print("打印房间数")
} else {

    print("无法打印房间数")
}

//链接多个链接(链条)

class  PersonB {
    var residence:ResidenceB?//nil
}
class ResidenceB {
    var address:Address?
}
class Address {
    var street:String?
}

let Libai=PersonB()
let LibaiHouse = ResidenceB()
Libai.residence=LibaiHouse

let libAddress=Address()
//赋值
LibaiHouse.address=libAddress
libAddress.street="china street"

if let libStreet = Libai.residence?.address?.street { //可选链条
print("libai的地址为\(libStreet)")
} else {
print("无法检索住址")
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值