您的位置:首页 > 移动开发 > Swift

swift基础笔记4-类和结构体

2016-05-24 15:58 316 查看

类和结构体对比

类和结构体是人们构建代码所用的一种通用且灵活的构造体。我们可以使用完全相同的语法规则来为类和结构体

定义属性(常量、变量)和添加方法,从而扩展类和结构体的功能。

Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件。你所要做的是在 一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口。

类和结构体对比

Swift 中类和结构体有很多共同点。共同处在于:

• 定义属性用于存储值

• 定义方法用于提供功能

• 定义附属脚本用于访问值

• 定义构造器用于生成初始化值

• 通过扩展以增加默认实现的功能 • 实现协议以提供某种标准功能

与结构体相比,类还有如下的附加功能:

• 继承允许一个类继承另一个类的特征

• 类型转换允许在运行时检查和解释一个类实例的类型 • 解构器允许一个类实例释放任何其所被分配的资源

• 引用计数允许对一个类的多次引用

定义

类和结构体有着类似的定义方式。我们通过关键字 class 和 struct 来分别表示类和结构体,并在一对大括号中定 义它们的具体内容

以下是定义结构体和定义类的示例:

struct Resolution { var width = 0 var height = 0
}
class VideoMode {
var resolution = Resolution() var interlaced = false
var frameRate = 0.0
var name: String?
}


示例说明:在上面的示例中我们定义了一个名为 Resolution 的结构体,用来描述一个显示器的像素分辨率。这个结构体包含 了两个名为 width 和 height 的存储属性。存储属性是捆绑和存储在类或结构体中的常量或变量。当这两个属性 被初始化为整数 0 的时候,它们会被推断为 Int 类型。

在上面的示例中我们还定义了一个名为 VideoMode 的类,用来描述一个视频显示器的特定模式。这个类包含了 四个储存属性变量。第一个是 分辨率 ,它被初始化为一个新的 Resolution 结构体的实例,具有 Resolution 的 属性类型。新 VideoMode 实例同时还会初始化其它三个属性,它们分别是:

初始值为 false (意为“非隔行扫描 视频”)的 interlaced ;

回放帧率初始值为 0.0 的 frameRate ;

值为可选 String 的 name 。 name 属性会被 自动赋予一个默认值 nil ,意为“没有 name 值”,因为它是一个可选类型。

类和结构体实例

生成结构体和类实例的语法非常相似:

let someResolution = Resolution() let someVideoMode = VideoMode()

结构体和类都使用构造器语法来生成新的实例。构造器语法的最简单形式是在结构体或者类的类型名称后跟随一 对空括号

属性访问

通过使用点语法(dot syntax),你可以访问实例中所含有的属性,具体不多说了,应该都知道。示例:

someVideoMode.resolution.width = 1280

注意: 与 Objective-C 语言不同的是,Swift 允许直接设置结构体属性的子属性。上面的例子,就是 直接设置了 someVideoMode 中 resolution 属性的 width 这个子属性,以上操作并不需要重新设置 resolutio n 属性

结构体类型的成员逐一构造器

所有结构体都有一个自动生成的成员逐一构造器,用于初始化新结构体实例中成员的属性。新实例中各个属性的

初始值可以通过属性的名称传递到成员逐一构造器之中:

let vga = Resolution(width:640, height: 480) 与结构体不同,类实例没有默认的成员逐一构造器。

结构体和枚举是值类型

值类型被赋予给一个变量、常量或者本身被传递给一个函数的时候,实际上操作的是其的拷贝。

实际上,在 Swift 中,所有的基本类型:整数(Integer)、浮点 数(floating-point)、布尔值(Boolean)、字符串(string)、数组(array)和字典(dictionary),都是值 类型,并且都是以结构体的形式在后台所实现。

类是引用类型

与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,操作的是引用,其并不是拷贝。因此,引用的是已存在的实例本身而不是其拷贝。具体不多说

因为类是引用类型,有可能有多个常量和变量在后台同时引用某一个类实例。(对于结构体和枚举来说,这并不成立。因为它们作为值类型,在被赋予到常量、变量或者传递到函数时,其值总是会被拷贝。)

为了判断两个常量或变量引用的是否是同一个实例,swift创建了新的恒等运算符:

• 等价于 ( === )

• 不等价于 ( !== )

请注意 “等价于” (用三个等号表示,===) 与 “等于” (用两个等号表示,==)的不同:

• “等价于”表示两个类类型(class type)的常量或者变量引用同一个类实例。

• “等于”表示两个实例的值“相等”或“相同”,判定时要遵照类设计者定义定义的评判标准,因此相比 于“相等”,这是一种更加合适的叫法。

struct Resolution {
var width = 0
var height = 0
}
class VideoModel {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name:String?
}
func objectDemoWithClassAndStructe(){

//1 实例定义
var someResolution = Resolution()
let someVideoModel = VideoModel()
print(someVideoModel)

//2 属性访问
someResolution.width = 320

//3 结构体类型的成员逐一构造器
let newResolution = Resolution(width: 320, height: 480)
print(newResolution) //Resolution(width: 320, height: 480)

//4 结构体是值类型
var copyResolution = newResolution
copyResolution.height = 560
print(newResolution) //Resolution(width: 320, height: 480)
print(copyResolution)//Resolution(width: 320, height: 560)

//5 类是引用类型
let originVidelModel = VideoModel()
originVidelModel.resolution = someResolution
print(originVidelModel.resolution)

let copyVideoModel = originVidelModel
copyVideoModel.resolution = newResolution
print(originVidelModel.resolution)
print(copyVideoModel.resolution)

if originVidelModel === copyVideoModel {
print("originVidelModel and copyVideoModel has the same VideoModel instance")
}
//print:originVidelModel and copyVideoModel has the same VideoModel instance

}


指针

如果你有 C,C++ 或者 Objective-C 语言的经验,那么你也许会知道这些语言使用指针来引用内存中的地 址。一个 Swift 常量或者变量引用一个引用类型的实例与 C 语言中的指针类似,不同的是并不直接指向内存中的 某个地址,而且也不要求你使用星号(*) 来表明你在创建一个引用。Swift 中这些引用与其它的常量或变量的定 义方式相同。

类和结构体的选项

在你的代码中,你可以使用类和结构体来定义你的自定义数据类型

然而,结构体实例总是通过值传递,类实例总是通过引用传递。这意味着两者适用不同的场景。

按照通用的准则,当符合一条或多条以下条件时,可以考虑构建结构体:

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

2.有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用

3.任何在结构体中存储的值类型属性,也将会被拷贝,而不是被引用。

4.结构体不需要去继承另一个以存在的类型的属性或行为。

在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的

自定义数据构造都应该是类,而非结构体。

字符串,数组和字典的赋值与复制

Swift 中   和 字典(Dictionary) 类型均以结构体的形式实现。这意味着String,Array,Dictionary类型数据被赋值给新的常量或变量,或者被传入函数或方法中时,它们的值会发生拷贝行 为(值传递方式)。

字符串(String) ,数组(Array)、Objective-C中 字符串(NSString) , 数组(NSArray) 和 字典(NSDictionary) 类型均以类的形式实现,这 与Swfit中以值传递方式是不同的。NSString,NSArray,NSDictionary在发生赋值或者传入函数(或方 法)时,不会发生值拷贝,而是传递已存在实例的引用

swift初学,留下笔记,不喜勿喷,欢迎交流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: