- 对象
class Student{ var name: String = ""; var age: Int = 0; init(name: String ,age:Int) { self.name = name self.age = age } } let stu = Student(name: "xiao", age: 18) print("姓名: (stu.name)")//姓名: xia
- 结构体
struct Person{ var name: String = ""; var age: Int = 0; init(name: String ,age:Int) { self.name = name self.age = age } } let person = Person(name: "xiao", age: 18) print("姓名: (person.name)")//姓名: xiao
结构体不需要考虑引用计数,接头体是值赋值,就是a赋值给b,如果改变b,则a不变,举例
let person = Person(name: "xiao", age: 18) print("姓名: (person.name)")//姓名: xiao var per1 = person; per1.name = "da" print("姓名: (person.name)")//姓名: xiao
属性的使用,以及注意点
let的注意点
struct Person{ var name: String = ""; // let声明的属性可以在init里面赋值,前提是不能设置默认值,比方说设置 let age: Int? = 0,如果在init里面重新赋值就会报错 let age: Int? init(name: String ,age:Int) { self.name = name self.age = age } } let person = Person.init(name: "xiaoming", age: 18); print(person.age!)//18 person.age = 19 //报错,因为age是let声明的常量,不能在init之外的地方修改
属性只有get,没有set方法设置
struct Person{ var name: String = ""; var age: Int{ get{ return 10; } } init(name: String ,age:Int) { self.name = name // self.age = age; 报错,因为属性没有set方法 } }
等价于
class Person{ var name : String{ return "小明" } } var person = Person(); //person.name = "xiaoming" //报错,因为没有set方法 print(person.name)//小明
如果属性get和set方法都需要,则需要调用
Class Person{ var _name = "" var name : String{ get{ return _name } set{ _name = newValue } } } var person = Person(); person.name = "xiaoming" print(person.name)//xiaoming
懒加载
class Person { lazy var sun = Sun() // `var` 关键字是必须的,不然会报错 }
计算属性
class sample { var no1 = 0.0, no2 = 0.0 var length = 300.0, breadth = 150.0 var middle: (Double, Double) { get{ return (length / 2, breadth / 2) } set(axis){ no1 = axis.0 - (length / 2) no2 = axis.1 - (breadth / 2) } } } var result = sample() print(result.middle)//(150.0, 75.0) 或者这么写也没有问题 print("(result.middle.0) (result.middle.1)") result.middle = (0.0, 10.0) print(result.no1)//-150.0 print(result.no2)//-65.0
继承和强转
class Person{ var name:String? init(name:String) { self.name = name; } } class Student: Person { var number:String? init(name: String,number:String) { super.init(name: name); self.number = number; } //override 如果和父类的构造方法一样,这个必须加,不然报错 override init(name: String) { super.init(name: name); } } //var stu1 = Student(name: "xiaoming", number: "2019091012") //print(stu1.name!)//输出小明 // //if(stu1 is Person){//检查类型 // print("person:(stu1.name!)")//输出:stu1:xiaoming //} // //let stu2 = stu1 as? Person //as?不确定转成功 as!强致性转 //print("stu2:(stu1.name!)")//输出: stu2:xiaomin //var person1 = Person(name: "huahua") //let person2 = person1 as? Student //print("person2:(person2.name)")//报错,类只能向上转,不能向下转
总结一下,既然类和结构体的用法差不多,我们需要什么怎么选择呢
• 封装少量、简单的数据的时候;
• 数值传递时数据是被拷贝的时候;
• 不需继承的时候。