每天学一点Swift----面向对象上(三)
四.值类型和引用类型
1.前面已经提到过,Swift中的类是引用类型,而枚举、结构体是只类型。
2.对于前面的例子var p =Person()来说,程序会先在堆内存里初始化一个Person实例,然后在栈内存里声明一个Person类型的变量,这个Person类型的变量实际上是一个引用,它指向实际的Person实例。所以栈内存里面的引用变量并没有真正存储实例的存储属性,实例的存储属性数据实际是放在堆内存里的。----这里可以看出,引用的实质就是指针,不过比指针更加灵活,方便。
3.当类的对象被创建成功后,Swift不允许直接访问堆内存中的对象,只能通过该实例对象的引用取操作该对象。
4.栈内存里面可以有多个引用指向堆内存里的同一个对象。
5.结构体与类是不同的,在栈内存中的结构体变量本身就保存了该结构体实例,当程序把结构体实例赋值给一个变量时,系统会将该结构体实例重新复制一份,并将该副本赋值给变量。
6.由于Swift把枚举、结构体当成值类型处理,无论赋值,还是传递参数,值类型的实例都需要被复制副本。因此Swift必须将枚举、结构体设计成“轻量级”的面向对象类型,所以枚举、结构体都不支持继承。
五.引用类型的比较
1.在前面的运算符介绍中,提到过两个运算符:===和!==。这两个运算符只能用于引用类型变量的比较。用来比较两个引用类型的变量是否指向同一个实例。
2.当两个引用类型的变量指向同一个实例时,===比较的结果为true,!==比较的结果为false;如果两个引用变量指向的实例不同时,则两个比较运算符的结构也互反。
六. self关键字
1. Swift提供类一个self关键字,self关键字总是指向该方法的调用者----类比java,其实就是java中this关键字。
2.在实例方法中,self表示调用该方法的实例;在类型方法中,self表示调用该方法的类型。
3.使用场景:在局部变量和存储属性重名的情况下,局部变量会隐藏存储属性。为了在方法中强行引用存储属性,也可以使用self关键字进行区分:
class Dog
{
var name : String = ""
var age : Int = 2
init(name:String, age:Int)----在swift中构造器用init,self表示当前类;在Java中构造器是类名,this表示当前类
{
self.name = name;
self.age = age;
}
func info()
{
print("my name is \(name), age is : \(age)")
}
}
补充性建议,大部分来自Apple的官方文档:
当程序需要定义一个自定义类型时,应该用类,还是结构体。一般来说,满足以下一个或多个条件时,应该考虑使用结构体:
(1)结构体的主要目标是用于封装少量相关的简单数据值。
(2)如果程序需要让该实例在赋值或参数传递时会自动复制副本,则应该使用结构体。
(3)如果程序明确该类型无须继承另一个已有的类或被其他继承,则应该使用结构体。
(4)例如如下几种情况,就可以使用结构体
几何形状的大小,使用结构体封装两个double属性,表示width,height;封装一个范围;封装一个三维坐标系。
(5)在面向对象编程的时候,绝大多数情况下是使用自定义类的。