这是我参与更文挑战的第1天,活动详情查看: [更文挑战](juejin.cn/post/696719…
写在开头
自己的Swift15天学习计划来到了class篇;
今天主要分享主题:class 和 struct 的异同点
类和结构体使用上都非常相似,可以使用它们来创建具有属性和方法的新数据类型。类拥有继承特性,这是一个非常有用重要且复杂的功能,他可以使我们基于已有类创建出一个新类;但在开发iOS App中我们就必须得使用它,但过度使用会使代码和性能变得臃肿和低效;保持代码简单,永远是优秀程序员应该精进的事情;
“any fool can write code that a computer can understand, but good programmers write code that humans can understand.” –Martin Fowler
类和结构体有5个不同点的
1. 成员初始化构造器
class有默认的无参构造函数 ,struct没有默认的无参构造函数,且只能声明有参的构造函数。
class Dog {
var name: String
var breed: String
init(name: String, breed: String) {
self.name = name
self.breed = breed
}
}
let myDog = Dog(name: "小狮子", breed: "Poodle")
struct Dog {
var name: String
var breed: String
}
复制代码
2. 继承
class可以继承类、接口和被继承,struct只能继承接口,不能被继承;
class Dog {
var name: String
var breed: String //品种
init(name: String, breed: String) {
self.name = name
self.breed = breed
}
}
复制代码
class Poodle: Dog {
init(name: String) {
super.init(name: name, breed: "Poodle")
}
}
复制代码
子类可重载父类的方法
class Dog {
func makeNoise() {
print("汪汪汪!")
}
}
class Poodle: Dog {
override func makeNoise() {
print("Yip!")
}
}
复制代码
Final
final class Dog {
var name: String
var breed: String
init(name: String, breed: String) {
self.name = name
self.breed = breed
}
}
复制代码
当你不想别人通过继承你的类来重写方法改变某些你不希望的行为,可以使用final 关键字能阻断其他类继承
3. 拷贝对象
当你拷贝struct时,会得到两分不同数据对象,改变其中任意对象不会互相影响;当你拷贝的是一个类的时候, 两个对象指向的是同一个对象,修改其中一个,另外一个随着也发生了变更;
作为参数传递时,class变量以按址方式传递,而struct变量是以按值方式传递的。
class Singer {
var name = "五月天"
}
var singer = Singer()
print(singer.name) // 五月天
var singerCopy = singer
singerCopy.name = "周杰伦"
print(singer.name) // 周杰伦
复制代码
把 class Singer
改成 struct Singer
则得到两个不同歌手
4. 析构函数(deinit)
class 有析构函数,struct 没有; 析构函数是在实例释放发生前一步被自动调用,class不能主动调用自己的析构函数,实例的析构函数被调用时,实例才会被释放,通常我们可以做一些清除工作。 class实例由垃圾回收机制来保证内存的回收处理,而struct变量使用完后立即自动解除内存分配;
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
复制代码
5.可变性(Mutability)
第五个不同点:class 和 contant 处理常量方式上也不一样; 如果你有一个常量的 struct ,那么里面定义的变量不能随便改变,因为本身就是一个常量值;但是如果你是一个常量的class,这个属性值是能被修改的;也不需要使用 mutating关键字来修饰后才能改;
所以类不管是正常创建的还是被定义成constant 都能更改属性的值
struct Singer {
var name = "周杰伦"
}
let s = Singer()
s.name = "五月天" // 报错
print(s.name)
复制代码