澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

结构体和类

2019-07-06 作者:www.8455.com   |   浏览(136)

 

存储属性
其实Swift中的存储属性就是以前学习OC中的普通属性, 在结构体或者类中定义的属性, 默认就是存储属性
*/

1).存储属性

//*---------------------结构体-------------*/

/*

struct Person {
var name: String
var age: Int
}
var p:Person = Person(name: "lnj", age: 30)
p.name = "hm"
p.age = 50

类和结构体中的属性,无特殊处理,都是存储属性,即属性开辟了内存空间,可以存储值。

//swift结构体也具有封装的概念

 存储属性

/*
常量存储属性
常量存储属性只能在定义时或构造时修改, 构造好一个对象之后不能对常量存储属性进行修改
*/

存储属性分为常量存储属性和变量存储属性,常量存储属性只可以在定义的时候赋初值,后续不可以更改

//swift结构体比OC C语言里面的结构体更加进了一步,里面可以有方法,更接近我们的类

 其实Swift中的存储属性就是以前学习OC中的普通属性, 在结构体或者类中定义的属性, 默认就是存储属性

struct Person2 {
var name: String
var age: Int
let card: String // 身份证
}
var p2: Person2 = Person2(name: "lnj", age: 30, card: "123456")
p2.name = "hm"
p2.age = 50
// 构造好对象之后不能修改常量存储属性
//p2.card = "56789"

struct Rect {

   let width : Double = 10

   var height : Double

}

var _ = Rect(height: 100)

//结构体的定义格式 struct结构体名{成员变量}

 */

/*
结构体和类常量与存储属性的关系
结构体和枚举是值类型
类是引用类型
*/

结构体常量对象,他本身是一个常量,其次,它对应的对象也是常量,不可以被修改

struct rect {

 

struct Person3 {
var name: String
var age: Int
}
let p3: Person3 = Person3(name: "lnj", age: 30)
// 因为结构体是值类型, 所以不能修改结构体常量中的属性
// 不能修改结构体/枚举常量对象中的值, 因为他指向的对象是一个常量
//p3.name = "hm"
// 不能修改结构体常量对象的值
//p3 = Person(name: "hm", age: 50)

let rect1 : Rect = Rect(height: 100)   // 常量rect1的height属性可以通过点语法进行后续修改

    var width:Double //按构造方法赋初值

struct Person {

class Person4 {
var name: String = "lnj"
var age: Int = 30
}
let p4:Person4 = Person4()
// 可以修改类常量中的值, 因为他指向的对象不是一个常量
p4.name = "hm"
// 不可以修改类常量的指向
//p4 = Person4()

类常量对象,他本身是一个常量,但他对应的成员属性,可以通过他来进行修改

    var height:Double

    var name: String

/*
延迟存储属性
Swift语言中所有的存储属性必须有初始值, 也就是当构造完一个对象后, 对象中所有的存储属性必须有初始值, 但是也有例外, 其中延迟存储属性可以将属性的初始化推迟到该属性第一次被调用的时候
懒加载应用场景:
1.有可能不会用到
2.依赖于其它值
*/


    //方法

    var age: Int

class Line {
var start:Double = 0.0
var end: Double = 0.0
// 如果不是lazy属性, 定义的时候对象还没有初始化, 所以不能访问self
// 如果加上lazy, 代表使用时才会加载, 也就是使用到length属性时才会调用self,
// 而访问一个类的属性必须通过对象方法, 所以访问时对象已经初始化完成了, 可以使用self
lazy var length: Double = self.getLenght()
// 通过闭包懒加载
lazy var container: Array<AnyObject> = {
print("懒加载")
// return self.end - self.start
var arrM = []
return arrM as [AnyObject]
}()
func getLenght() ->Double
{
print("懒加载")
return end - start
}
}
var line = Line()
line.end = 150.0
//print(line.getLenght())
print("创建对象完毕")
print(line.length)
var arrM = line.container
arrM.append("1")
arrM.append(5)
print(arrM)

2).延迟存储属性

    func getHeightWidth() -> (x:Double,y:Double)//->返回类型位元组

}

/*
计算属性
1.Swift中的计算属性不直接存储值, 跟存储属性不同, 没有任何的"后端存储与之对应"
2.计算属性用于计算, 可以实现setter和getter这两种计算方法
3.枚举不可以有存储属性, 但是允许有计算属性
setter 对象.属性 = 值
getter var value = 对象.属性
*/

swift中所有的存储属性必须有初始值,也就是当构造完一个类或者结构体的对象后,对象中所有的存储属性必须有初始值。

    {

var p = Person(name: "xiaohange", age: 26)

struct Rect {
var origion: (x: Double, y: Double) = (0, 0)
var size: (w: Double, h: Double) = (0, 0)
// 由于center的值是通过起点和宽高计算出来的, 所以没有必要提供一个存储属性
// var center: (x: Double, y: Double) = (0, 0)
var center: (x: Double, y: Double) {
get{
// print("get")
return (origion.x size.w/2, origion.y size.h/2)
}
// set(newCenter){
set{
// print("set (newCenter)")
// 注意: 计算属性不具备存储功能, 所以不能给计算属性赋值, 如果赋值会发生运行时错误
// 注意: setter可以自己传递一个参数, 也可以使用系统默认的参数newValue
// 如果要使用系统自带的参数, 必须删除自定义参数
// origion.x = newCenter.x - size.w / 2
// origion.y = newCenter.y - size.h / 2
origion.x = newValue.x - size.w / 2
origion.y = newValue.y - size.h / 2
}
}
}
var r = Rect()
r.origion = (0, 0)
r.size = (100, 100)
//r.center = ((r.origion.x r.size.w) / 2, (r.origion.y r.size.h) / 2)
print("center.x = (r.center.x) center.y = (r.center.y)")
r.center = (100, 100)
print("origion.x = (r.origion.x) origion.y = (r.origion.y)")
print("center.x = (r.center.x) center.y = (r.center.y)")

但是也有例外,其中,延迟存储属性可以将属性的初始化向后推迟到该属性第一次被调用的时候。

        return(width,height)

print("name = (p.name) age = (p.age)")

/*
只读计算属性
对应OC中的readonly属性, 所谓的只读属性就是只提供了getter方法, 没有提供setter方法
*/

延迟存储属性适用场景:

    }

 

class Line2 {
var start:Double = 0.0
var end: Double = 0.0
// 只读属性, 只读属性必须是变量var, 不能是常量let
// 例如想获取长度, 只能通过计算获得, 而不需要外界设置, 可以设置为只读计算属性
var length: Double{
// 只读属性的简写, 可以省略get{}
// get{
return end - start
// }
}
}

  1.属性不适合一开始就初始化,取决于外部因素

    func sumHeightWidth() -> (Double)

p.name = "HaRi"

var line2 = Line2()
line2.end = 100
print(line2.length)

  2.属性有可能从来不会用到,但是他的初始化有需要较长的时间

    {

p.age = 28

/*
属性观察器,类似OC中的KVO, 可以用于监听属性什么时候被修改, 只有属性被修改才会调用
有两种属性观察器:
1.willSet, 在设置新值之前调用
2.didSet, 在设置新值之后调用
可以直接为除计算属性和lazy属性之外的存储属性添加属性观察器, 但是可以在继承类中为父类的计算属性提供属性观察器
因为在计算属性中也可以监听到属性的改变, 所以给计算属性添加属性观察器没有任何意义
*/
class Line3 {
var start:Double = 0.0{
willSet{
print("willSet newValue = (newValue)")
}
didSet{
print("didSet oldValue = (oldValue)")
}
}
var end: Double = 0.0
}
var l = Line3()
l.start = 10.0

class student {

   var name : NSString = ""

   lazy var averageScore : Double = 0

}

        return(width height)

print("name = (p.name) age = (p.age)")

/*
类属性
在结构体和枚举中用static
在类中使用class, 并且类中不允许将存储属性设置为类属性
*/


    }

 

struct Person5 {
// 普通的属性是每个对象一份
var name: String = "lnj"
// 类属性是素有对象共用一份
static var gender:String = "man"
static var age:Int{
return 30
}
func show()
{
print("gender = (Person5.gender) name = (name)")
}
}
var p5 = Person5()
//print("gender = (p.gender)")
print("gender = (Person5.gender)")
var p6 = Person5()
// 类属性是所有对象共用一份
print("gender = (Person5.gender)")
p5.show()
// 可以将计算属性设置为类属性
print("age = (Person5.age)")

3).计算属性

}

/*

class Person6 {
// 普通的属性是每个对象一份
var name: String = "lnj"
// 类中不允许将存储属性定义为类属性
// class var gender:String = "man"
// 类中只能将计算属性定义为类属性
class var age:Int{
return 30
}
func show()
{
print("age = (Person6.age)")
}
}
var p7 = Person6()
print("age = (Person6.age)")
p7.show()

1.swift中的计算属性不直接存储值,跟存储属性不同,没有任何的“后端存储与之对应”(不占用存储空间)。

 

 常量存储属性

2.计算属性用于计算,可以实现setter和getter这两种方法。

//声明结构体对象 var 变量名:结构体类型=结构体类型(参数)

 常量存储属性只能在定义时或构造时修改, 构造好一个对象之后不能对常量存储属性进行修改

3.枚举enum不可以有存储属性,但可以有计算属性。

//swift要求当定义一个结构体对象的时候,必须要对里面的变量赋一个固定的值

 */

对象.属性 = value  --- setter方法

//结构体的构造方法(就是创建了一个结构体对象,首先他要分配内存空间(这一步由系统自行帮我们完成),分配完内存就会立即调用我们的初始化方法(构造方法)来对变量赋初值)

 

let value = 对象.属性 --- getter方法

 

struct Person2 {

struct MyRect {

   var origin : (x : Double , y : Double) = (0 , 0)  // 存储属性

   var size : (w : Double , h : Double) = (0 , 0)    // 存储属性

   var center : (x : Double , y : Double) {            //计算属性

     get {

          return (origin.x size.w / 2, origin.y size.h / 2)

      }

     set (n) {

       //origin是存储属性 可以被赋值

      //center是计算属性 不可以被赋值

       //newValue是系统提供的默认setter值 : set �{ origin.x = newValue.x - size.w / 2 }

      origin.x = n.x - size.w / 2

       origin.y = n.y - size.h / 2

     }

   }

}

//swift的结构体初始化方法有两种 一种是成员逐一构造器var rect1:rect=rect(width: 100, height: 100) 一种是系统默认的不带任何参数的初始化方法struct rect {

    var name: String


//var width:Double=0.0 //按构造方法赋初值

    var age : Int

4).只读计算属性

//var height:Double=0.0

    let card: String // 常量 ID Card

只提供get方法,不提供set方法的属性,称为只读计算属性

//}

}

struct MyRect {

    var size : (w : Double , h : Double) = (0 , 0) // 存储属性

    var center : (x : Double , y : Double) { //计算属性

   //    get {

            return (size.w / 2,  size.h / 2)

   //     }

 }

}      // 只读计算属性  get方法的关键字get和括号可以省略掉

//var rect1:rect=rect()

var p2 = Person2(name: "HaRi", age: 24, card: "1234")


var rect1:rect=rect(width: 100, height: 100)

p2.name = "helloName"

5).属性观察器

println("(rect1.width),(rect1.height)")

p2.age = 25

观察属性的变化,在属性被修改时,调用我们事先写好的代码去执行额外的动作,类似于OC中的KVO

 

// 构造好对象以后不能修改常量存储属性

属性观察器有两种:

//调用

//p2.card = "333" Error澳门新萄京官方网站,!

  1. willSet 在设置新值时,赋值前调用

var c_n=rect1.getHeightWidth()

 

  2. didSet 在新值被赋之后调用

println(c_n)

/*

可以直接为除lazy属性之外的存储属性添加属性观察器,也可以在继承类中为父类的计算属性提供属性观察期

 

 结构体和类常量与存储属性的关系

struct MyRect {

    var center : (x : Double , y : Double) {

          willSet {

                print("(newValue.x)")

           }

          didSet {

               print("(oldValue.x)")

          }

     }

}

var w_h=rect1.sumHeightWidth()

 结构体和枚举是值类型


println(w_h)

 类是引用类型

6).类型属性

 

 */

1.也就是“类”本身定义属性,这样的属性不隶属于某一个“对象”,可以认为所有的对象公用这个属性;

//结构体的整体赋值

 

2.结构体或者枚举可以定义存储或者计算型类属性,而类只能定义计算型类属性,不可以定义存储类型

var rect3 = rect1

struct Person3 {

struct MyRect {

     static var center : (x : Double , y : Double) = (10 ,10)   //如果在类中  static需要换为class关键字

}

MyRect.center = (10,11)

//整体赋值后的可能性有两种(1)rect3与rect1指向同一个内存空间(2)rect3与rect1内容一样,内存空间不一样

    var name: String

//验证方法有两种可以直接打印内存地址还有一种是改变值如果指向统一内存空间则赋值后的也应该改变成一样

    var age : Int

rect1.width = 20

}

println(rect1.width)

let p3 = Person3(name: "hjq", age: 26)

println(rect3.width)

// 1.因为结构体是值类型, 所以不能修改结构体常量中的属性;

//值未变可以知道是第二种 即赋值后内容一样,内存空间不一样

// 2.不能修改结构体 / 枚举常量对象中的值, 因为他指向的对象是一个常量;

 

//p3.name = "hiName"  Error!

/*----------------------类-----------------*/

//p3 = Person3(name: "hiName", age: 27)   Error!

//类与结构体在定义的格式上没有太大的区别,类在创建的时候必须要给里面的变量附一个初始值,因为类与结构体不一样,它没有成员逐一构造器

 

class rectww {

 

    var width:Double=0.0

class Person4 {

    var height:Double=0.0

    var name: String = ""

}

    var age: Int = 20

var re:rectww=rectww()

}

println("(re.width),(re.height)")

let p4:Person4 = Person4()

 

// 可以修改类中常量中的值, 因为他们指向的对象不是一个常量

//类的整体赋值

p4.name = "hello xiaohange"

//指向同一内存空空间

// 不可以修改类常量的指向

var ss = re

//p4 = Person4()  Error!

re.width = 200

 

println(re.width)

 

println(ss.width)

/*

//===恒等 !==不等 只能用类

 延迟存储属性

if ss===re{

 Swift语言中所有的存储属性必须有初始值, 也就是当构造完一个对象后, 对象中所有的存储属性必须有初始值, 但是也有例外, 其中延迟存储属性可以将属性的初始化推迟到该属性第一次被调用的时候

    println("同一个类")

 懒加载应用场景:

}

 1.有可能不会用到

else

 2.依赖于其它值

{

 */

    println("不同")

 

}

class Line {

 

    var start:Double = 0.0

 

    var end:Double = 0.0

结构体和类。 

    

//存储属性

    // 1.如果不是 lazy属性, 定义的时候对象还没有初始化, 所以不能访问self;

//常量存储属性 :只能在构造对象的时候改变值之后不被允许改变

    // 2.如果加上 lazy, 代表使用时才会加载, 也就是使用到length属性时才会调用self;

//延迟存储属性

    // 3.而访问一个类的属性必须通过对象方法, 所以访问时对象已经初始化完成了, 可以使用self

 

    lazy var length: Double = self.getLength()

//结构体常量和类常量与存储属性的关系

    

//结构体常量常量对象,本身是一个常量,对应的属性不可以通过修改它改变

    // 通过闭包懒加载

struct person{

    lazy var container: Array<AnyObject> = {

    let name:NSString = "张三"//常量

        print("懒加载")

    var age:Int = 10//变量

        

}

        var arrrM:Array<Int> = []

let per:person=person(name: "李四", age: 20)//在构造对象的时候可以改变值之后不被允许改变 例如会报错//per.name = "王五" //per.age = 39

//        return self.end - self.start   Error!

println(per.name)

        return arrrM as [AnyObject]

 

    }()

//类本身是一个常量,属性可以通过修改它改变

    

class person1{

    func getLength() -> Double

    let name1:NSString = "张三"//常量

    {

    var age1:Int = 10//变量

        print("懒加载")

}

        return end - start

let per1:person1=person1()//在构造对象的时候可以改变值之后不被允许改变 例如会报错

    }

//per1.name1 = "王五"

}

per1.age1 = 39

var line = Line()

println(per1.name1)

line.end = 200.0

 

//print(line.length())  Error!

//延迟存储属性

print("创建对象完毕")

/*

print(line.length)

swift语言中所有的存储属性都必须要有初始值,也就是当调用完构造方法后对象中的所有变量都应该有一个初始值,但是延迟存储属性很例外,它的赋值并不都在调用构造方法的时候被初始化,而是在第一次被调用的时候初始化

var arrM = line.container

*/

arrM.append("1" as AnyObject)

 

arrM.append(5 as AnyObject)

struct student {

print(arrM)    // [1, 2, 3, 1, 5]

    var name:String

 

    var chinese:Double

 

    var math:Double

/*

    func showMyStudent(){

 计算属性

        println("姓名:(name),语文成绩:(chinese),数学成绩:(math)")

 1.Swift中的计算属性不直接存储值, 跟存储属性不同, 没有任何的"后端存储与之对应"

    }

 2.计算属性用于计算, 可以实现setter和getter这两种计算方法

}

 3.枚举不可以有存储属性, 但是允许有计算属性

class myClass {

 setter 对象.属性 = 值

    var array:[student]=[]

 getter var value = 对象.属性

    lazy var score :Double = self.getScore()//延迟

 */

    func getScore()->Double{

 

        println("888888")

struct Rect {

        var t:Double = 0

    var origion:(x: Double, y: Double) = (0, 0)

        for i in array

    var size:(w: Double, h: Double) = (0, 0)

        {

    

            t =i.chinese

    // 由于center的值是通过起点和宽高计算出来的, 所以没有必要提供一个存储属性

            t =i.math

    var center:(x: Double, y:Double){

        }

        

        if array.count == 0

        get{

        {

            return (origion.x size.w/2, origion.y size.h/2)

            return 0

        }

        }

        

        else

        set{

        {

            // 注意: 计算属性不具备存储功能, 所以不能给计算属性赋值, 如果赋值会发生运行时错误

            //swif里面只有隐式类型推断,没有隐式类型转换

            // 注意: setter可以自己传递一个参数, 也可以使用系统默认的参数newValue

            return t/Double (array.count)

            // 如果要使用系统自带的参数, 必须删除自定义参数

        }

            origion.x = newValue.x - size.w / 2

    }

            origion.y = newValue.y - size.h / 2

    func show(){

        }

        for i in array

    }

        {

}

            i.showMyStudent()//直接调用方法

var r = Rect()

        }

r.origion = (0, 0)

    }

r.size = (100, 100)

}

//r.center = ((r.origion.x r.size.w) / 2, (r.origion.y r.size.h) / 2)    // 可以直接在结构体中获得, 此处可以省略

 

print("center.x = (r.center.x) , center.y = (r.center.y)")

let stu1 = student(name: "张三", chinese: 100, math: 100)

r.center = (100, 100)

let stu2 = student(name: "李四", chinese: 100, math: 100)

print("origion.x = (r.origion.x) , origion.y = (r.origion.y)")

//创建类的对象

print("center.x = (r.center.x) , center.y = (r.center.y)")

let c0 = myClass()

 

c0.array.append(stu1)//加到数组

 

c0.array.append(stu2)

/*

c0.show()

 只读计算属性

println(c0.getScore())

 对应OC中的readonly属性, 所谓的只读属性就是只提供了getter方法, 没有提供setter方法

println("********")

 */

 

class Line2 {

//计算属性

    var start: Double = 0.0

/*

    var end: Double = 0.0

1.swift中的计算属性不能直接存储数据,与我们的存储属性不同,没有任何的"后端存储与之对应",简单来说就是在对对象中各种不占用存储空间

    

2.计算属性用于计算,可以实现setter和getter两种方法

    // 只读属性, 只读属性必须是变量var, 不能是常量let

*/

    // 比如想获取length, 只能通过计算获得, 而不需要外界设置, 可以设置为只读计算属性

 

    var leghth: Double {

struct myRect {

        //只读属性可以省略get{}

    var origin:(x:Double,y:Double)=(0,0)//坐标

//        get{

    var size:(w:Double,h:Double)=(10,10)

            return end - start

    var center:(x:Double,y:Double)//中心点

//        }

        {

    }

            //getter方法 当只有getter方法为只读 可以简写为一句return (origin.x size.w/2,origin.y size.h/2)

}

            get{

var line2 = Line()

                return (origin.x size.w/2,origin.y size.h/2)

line2.end = 100

            }

print(line2.length)

           //setter方法

 

            set(n){

/*

                //当sette没有传递参数时用newValue来代替n

 属性观察器,类似OC中的KVO, 可以用于监听属性什么时候被修改, 只有属性被修改才会调用

                 origin.x=n.x-size.w/2

 有两种属性观察器:

                 origin.y=n.y-size.h/2

 1.willSet, 在设置新值之前调用

            }

 2.didSet, 在设置新值之后调用

    }

 可以直接为除计算属性和lazy属性之外的存储属性添加属性观察器, 但是可以在继承类中为父类的计算属性提供属性观察器

}

 因为在计算属性中也可以监听到属性的改变, 所以给计算属性添加属性观察器没有任何意义

var rect4 = myRect()

 */

rect4.size=(100,100)

 

rect4.origin=(10,10)

class Line3{

//rect4.center=(rect4.origin.x rect4.size.w/2,rect4.origin.y rect4.size.h/2)

    var start: Double = 0.0{

println(rect4.center)

        willSet{

 

            print("willSet newValue = (newValue)")

 

        }

//属性观察器

        didSet{

//用于观察属性变化,是指属性的值被修改时可以调用我们事先写好的一些代码段 类似oc中的kvo

            print("didSet oldValue = (oldValue)")

//swift存在两种属性观察器

        }

//1.willset 在设置新值的时候被调用的

    }

//2.didset 在新值设置之后被调用

    

//不可以给延迟属性添加观察器 其他的都可以

    var end: Double = 0.0

 

}

class rr {

var l = Line3()

    var a:String="nihao"{

l.start = 10.0

        willSet{

 

            println("willSet,改变之前的值:(a)")

 

            println(newValue)

/*

        }

 类属性

        didSet{

 在结构体和枚举中用static

            println("didSet,改变之后的值:(a)")

 在类中使用class, 并且类中不允许将存储属性设置为类属性

            println(oldValue)

 */

        }

struct Person5 {

    }

    //普通的属性是每个对象的一份

    

    var name: String = "hjq"

}

    //类属性是素有对象共用一份

//改变值 先创建类的对象

    static var gender: String = "Man"

var ass=rr()

    static var age: Int{

ass.a="hehe"

        return 25

 

    }

//总结 结构体为值传递 类为引用

    func show()

 

    {

        print("gender = (Person5.gender) name = (name)")

    }

}

var p5 = Person5()

//print("gender = (p5.gender)")  Error!

 

Person5.gender = "women"

 

print("p5 gender = (Person5.gender)")

 

var p6 = Person5()

// 类属性是所有对象共用一份

print("p6 gender = (Person5.gender)")

p5.show()

 

//可以将计算属性设置为类属性

print("age = (Person5.age)")

 

 

class Person6 {

    //普通的属性是每个对象一份

    var name: String = "hjq"

    //类中不允许将存储属性定义为类属性

//    class var gender: String = "man"   Error!

    //类中只能将计算属性定义为类属性

    class var age: Int {

        return 26

    }

    func show() {

        print("age = (Person6.age)")

    }

}

var p7 = Person6()

print("p7 age = (Person6.age)")

p7.show()

 

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:结构体和类

关键词: