Learn Swift Pt. 2
结构和类
Swift 中的结构体和类都可以存放数据和方法。 那么结构体和类有什么区别呢? 通常来讲,结构体是存储那些可以被当做值的对象,只用来存放封装的数据就可以了。
区别
类是引用类型的,然而结构体值类型的。这就说明,当你把类传入参数或者放在
=
右边时,传的是类的引用。而结构体只是单纯地被拷贝。 当把它们定义为 var
类型的时候,都可以改变成员变量并且更改它们(指针)的指向。 当用 let
修饰的时候,类和结构体有一些区别: - 常量类可以修改成员变量,但是不可以修改它的指向。 - 常量结构体成员和指向都不可被修改。定义一个类或结构体
class LocationInfo {
let name: String
let latitude: Double
let longitude: Double
//初始化函数,类中的成员必须在初始化中被初始化,除非它是 Optional 的
init(name: String, latitude: Double, longitude: Double) {
self.name = name
self.latitude = latitude
self.longitude = longitude
}
}
latitude
和 longitude
是相关的一组变量,可以把他们放进结构体里面。struct Location {
let latitude: Double
let longitude: Double
}
这样,我们的
LocationInfo
类就可以修改了。class LocationInfo {
let name: String
let location: Location
init(name: String, location: Location) {
self.name = name
self.location = location
}
}
但如果在现在想要构造一个
LocationInfo
的类得先要定义一个 Location
的结构,有些麻烦。 可以为类添加一个更方便的构造方法。convenience init(name: String, latitude: Double, longitude: Double) {
let location = Location(latitude: latitude, longitude: longitude)
self.init(name: name, location: location)
}
类的继承
class Location3D : LocationInfo {
let height: Double
init(name: String, height: Double, latitude: Double, longitude: Double) {
self.height = height
let location = Location(latitude: latitude, longitude: longitude)
super.init(name: name, location: location)
}
}
语法没什么的,当子类都只属于自己的成员时,初始化需要在自己的构造里面实现。 子类的构造里必须调用父类的
init
(不可以是 convenience init
),初始化父类里面的成员。当一个类不想让他被继承的时候,可以用
final
关键字修饰重载函数
当子类重载父类的函数时,前面需要加上
override
关键字。类的扩展(Class Extension)
类的扩展就是为类添加额外的功能,在 Swift 中可以添加属性和函数。 定义一个类的扩展:
class MyClass {
let foo1 = 123
let foo2 = 22
}
extension MyClass {
var foo3: Int {
return self.foo1 + self.foo2
}
}
其实把这些东西放到主类中也可以,但是为了逻辑的分离和代码的可读性,有时会添加类的扩展。
权限控制(Access Control)
类中的成员变量和方法都可以设置权限。 - public : 所有的东西都可以获取。(主要应用于单元测试, 因为是在不同的 target 里面) - internal : 同一个库和应用才有权限,这是默认的等级。(必须在同一个 target 里面, 最适合库来使用,可以隐藏不想暴露的代码) - private : 只有这个源代码文件可以获取