Swift -- 7.3 类和结构体

swift的类和结构体高度相似,无论是定义语法还是用法上,swift的类和结构体都具有高度的相似性

区别是:结构体不支持继承(自然也不支持类型转换了。。。。。这个,还不太理解)

结构体不支持定义析构器

结构体是值类型,而类是引用类型

 

苹果的官方文档中说结构体的使用场景不多,主要还是应该使用类

那么哪些场景需要用到结构体呢:

苹果的官方文档表示,当满足以下一个或多个条件时,应该使用结构体

*结构体的主要目的是用于封装少量相关的简单数据值

如果程序需要让该实例在赋值或参数传递时会自动复制副本,则应该使用结构体

如果程序明确该类型无须继承另一个已有的的类或被其他类继承,则可以考虑使用结构体

 

一个类中包含三种成员:构造器,属性,方法

swift语言通过类名后添加圆括号来表示调用构造器,从而返回该类的实例

如果程序员自己没有写构造器,系统会提供一个默认的无参的构造器,如果自己写了,系统就不提供默认的构造器

class修饰的成员(类成员)不能访问没有class修饰的成员(实例成员)

 

定义结构体和定义类的主要区别是:结构体不支持继承,因此结构体不能使用final修饰

如果程序员没有为结构体提供构造器,系统则会为该结构体提供两个构造器:一个无参的构造器,一个初始化所有存储属性的构造器

 

class,static两个修饰符的作用几乎完全相同,只是使用场景不同。定义类时,使用class修饰类中成员,将遮羞成员转成类型相关的成员,没有该修饰符的是实例成员;定义结构体或枚举时,使用static修饰枚举或结构体的成员,将这些成员转成类型相关的成员,没有该修饰符修饰的是实例成员,所以staticclass两个修饰符不会同时出现

 

swift语言要求类中定义的存储属性必须指定初始值,要么在定义时指定初始值,要么在构造器中指定初始值

 

swift的构造器隐式的将self作为返回值

 

定义和创建实例

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

//定义一个dog结构体
struct Dog
{
    var name : String
    var age : Int
    func run()
    {
        print("\(name) is running")
    }
}

//创建实例
var p6:Person
p6 = Person()
var p5 = Person()
var p7 = p6
p6.name = "sun"
p6.say("swift is so easy")
print(p6.name)
print(p5.name)
p6.name = "zhu"
print(p7.name)

var dogfff = Dog(name: "doggy", age: 4)
print(dogfff.age)
dogfff.run()
var dogggg = dogfff
dogggg.name = "happy"
print(dogfff.name)

 

使用===和!==来判断引用类型是否指向同一个实例

class User
{
    var name:String
    var age:Int
    init(name:String , age:Int)
    {
        self.name = name
        self.age = age
    }
}
var u1 = User(name: "abe", age: 12)
var u2 = User(name: "abe", age: 12)
print(u1 === u2)
var u3 = u1
print(u3 === u1)

struct Level {
    var grade:Int
}

var v1 = Level(grade: 1)
var v2 = Level(grade: 2)
//print(v1 === v2)   这里不能这样写,因为只有引用类型能这样比较

  

运算符重载

func == (left:User, right:User) -> Bool
{
    return left.name == right.name && left.age == right.age
}

func != (left:User, right:User) -> Bool
{
    return !(left == right)
}
var resultttt = u1==u2
print(resultttt)

  

存储属性

枚举不能定义实例存储属性,只有类和结构体才能定义实例存储属性;枚举,类,结构体都可以定义类型存储属性

  

在结构体中,声明的存储属性可以不赋予初始值,因为系统会自动生成一个构造器,用来赋予初始值

struct FixedLengthRange {
    var start: Int
    let length: Int
}
var rg = FixedLengthRange(start: 2, length: 10)
rg.start = 5

  

延迟存储属性

在第一次被调用时才会被计算初始值的属性,声明延迟存储属性需要使用lazy修饰符

延迟存储是一种延迟加载(lazy load)机制,当某个实例持有另一个创建成本较大的实例的引用时,使用延迟存储可以降低内存开销,从而提升程序性能

 

class Dept
{
    var id : Int
    var info : String
    init(id : Int)
    {
        self.id = id
        NSThread.sleepForTimeInterval(2)
        self.info = "2 second late"
    }
}
class User4 {
    var id:Int = 0
    lazy var dept = Dept(id: 20)//dept 属性会在被调用的时候才被初始化,提升了程序的性能
    var nicks = [String]()
}
var usersss = User4()
usersss.nicks.append("sun")
usersss.nicks.append("qiqiqi")
print(usersss.nicks)

  

计算属性

枚举,结构体,类都可以定义计算属性

 

enum Seasonnn
{
    case Spring, Summer, Fall, Winter
    var info:String{
        get{
            print("the get method is running")
            switch(self)
            {
            case .Spring:
                return "flower"
            default:
                return "no"
            }
        }
        set (newValue){
            print("the set method is running and the pragmatic is \(newValue)")
        }
    }
}
var s = Seasonnn.Spring
print(s.info)
s.info = "baby"

//简化的set方法
enum Seasonnn2
{
    case Spring, Summer, Fall, Winter
    var info:String{
        get{
            print("the get method is running")
            switch(self)
            {
            case .Spring:
                return "flower"
            default:
                return "no"
            }
        }
        set{
            print("the set method is running and the pragmatic is \(newValue)")
        }
    }
}

/*
声明只读的计算属性
没有set方法,只有get方法
这里可以省略get这个关键字和花括号
*/
enum Seasonnn3
{
    case Spring, Summer, Fall, Winter
    var info:String{
        get{
            print("the get method is running")
            switch(self)
            {
            case .Spring:
                return "flower"
            default:
                return "no"
            }
        }
    }
}
var ss = Seasonnn3.Spring

  

属性观察者机制

为了让程序能在属性被赋值时获得执行代码的机会,swift提供了属性观察者机制,属性观察者其实就是两个特殊的回调方法

willSet(newValue) 被观察的属性即将被赋值之前自动调用该方法

didSet(oldValue) 被观察的属性被赋值完成之后自动调用该方法

willSet部分可以显式指定

class People {
    var name:String = "" {
        willSet{
            if(newValue.characters.count > 6) || (newValue.characters.count < 2){
                print("the name you input is iligo")
            }
            else
            {
                print("set name success")
            }
        }
        didSet{
            print("set name over")
        }
    }
}
var jane = People()
jane.name = "d"
print(jane.name)//虽然这两个方法有监察作用,但是并不能阻止赋值的执行

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2016-06-16 14:57 车宝大人 阅读(...) 评论(...) 编辑 收藏