swift学习笔记之类和对象
发布时间:2020-12-14 06:56:59 所属栏目:百科 来源:网络整理
导读:// ---------------类和对象---------------- //1类的组成 // 类==属性+下属脚本+方法 //属性:它将值和特定的类关联 //下属脚本:访问对象,集合的快捷方式 //方法:实现某一特定的功能,类似于函数 //2类的创建 class 类名 { //} //3实例化对象 //var/let 对象
// ---------------类和对象----------------
//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,"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,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("无法检索住址")
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |