【iOS】Swift类的继承、构造方法、析构器等复习
一、继承与重写, 防止重写
1.1 基类, 不继承任何类. Swift不想OC或者Java中继承自Object类.定义一个类,不继承任何类,该类就是基类.
- class Person1{ //这个Person1就是基类
- func eat(){
- println("eat a pig!")
- }
- }
1.2 继承. Swift为单继承
- class XiaoMing1 : Person1{
- var name = "xiaoming"
- }
1.3 重写. 必须加关键字override. (OC,Java中是不必加的)
- class XiaoHong1 : Person1{
- override func eat() {
- super.eat(); //可以用super来调用父类中的属性与方法
- println("xiaohong eat a pig")
- }
- }
- var xh = XiaoHong1()
- xh.eat()
1.4 重写属性(存储属性与计算属性)
可以用get/set/willSet/didSet进行属性重写
可以将一个只读属性重写为一个读写属性,不可以将一个读写属性重写为一个只读属性
也就是说: 重写的范围只能是 小-->大 (类似Java)
子类重写父类的属性时, 不管父类是计算属性还是存储属性, 重写的过程就是重写其中的get/set等, 子类的override都是计算属性的格式
- class Person2{
- var name:String{ //计算属性
- set{
- println("Person2 set")
- }
- get{
- return "Person2"
- }
- }
- let age: Int = 10 //常量存储属性
- var height:Int = 175 //变量存储属性
- }
- class XiaoMing2 : Person2{
- override var name:String{
- set{
- super.name = newValue //将父类的值设置为新值
- println("XiaoMing2 set")
- }
- get{
- return "XiaoMing2"
- }
- }
- override var age : Int{ //如果父属性是var的话, 必须有get和set
- get{
- println(super.age)
- return 20
- }
- }
- override var height :Int{ //重写观察属性: 继承来的常量存储属性,只读计算属性不能添加观察器.
- didSet{ //注意有didSet,willSet的地方是不能出现get/set的
- println("didset----\(oldValue)")
- }
- willSet{
- println("willSet----\(newValue)")
- }
- }
- }
- var xm2 = XiaoMing2()
- xm2.name = "XM2"
- println(xm2.age)
- xm2.height = 10
1.5 防止重写(final). 与Java一样
- //可将final写在属性/方法/类等前面
- class Person3{
- final var name = "Person3"
- }
- class XiaoMing3{
- //override var name ...//这样会报错
- }
二、构造器
Swift中的构造器无返回值(OC中是返回id的), 它的主要任务是保证新实例在第一次使用前完成正确的初始化工作.
init() , 可以重载
2.1 默认构造器与带参数构造器, 继承器的重载
- class Person4{
- var name : String //必须初始化, 或者在构造函数中初始化
- //默认, 不带参数
- init(){ //无返回值
- name = "xuneng"
- }
- //带参数
- init(name :String){ //默认是以参数名作为外部参数名的
- self.name = name + "Hello" //和OC中相同, 用self.(Java中用this)
- }
- //带可选参数. 可选类型: 可以为空,也可以以后赋值. 初始化为nil
- var age:Int = 10
- init(name :String , age:Int?){
- self.name = name
- self.age = age! //可选参数必须确定有(加!号)才能赋值
- }
- }
- var p4 = Person4() //默认就是没有括号的
- var p4_1 = Person4(name: "xn4545945 ") //参数名作为外部参数名
- var p4_2 = Person4(name: "neng", age: 10)
2.1 指定构造器(Designated initializer)与便利构造器(convenience initializer)
2.1.1 指定构造器: 每个类必须至少有一个,用来确保所有值都进行初始化.(会根据父类的继承关系往上调用,完成父类的初始化)
- //Person4中的3个构造器都是指定构造器, 都需要进行所有成员变量的初始化
2.1.2 便利构造器(加convenience关键字):辅助性的构造器.可以用来同一个类中的指定构造器,也可以用来创建一个有特定输入的实例
- class Person5{
- var name : String //必须初始化, 或者在指定构造函数中初始化
- init(name :String){ //指定构造器
- self.name = name + "Hello"
- }
- convenience init(name :String , height:Int){ //便利构造器. 不需要全部初始化成员变量
- self.init(name:name)
- println(height)
- }
- }
- var p5 = Person5(name: "xn4545945", height: 175)
2.2 构造器链(概念): 规范指定构造器与便利构造器间的调用关系.
- //1) 规则1: 指定构造器必须调用其父类的指定构造器
- //2) 规则2: 便利构造器必须调用同一类中调用的其他构造器
- //3) 规则3: 便利构造器必须以调用一个指定构造器结束
一句话总结上面3个规律: 指定构造器是向上调用的,便利构造器是横向调用的.
2.3 两段式构造过程 (概念)
第一个阶段:每个存储型属性通过引入它们的类的构造器来设置初始值。
第二阶阶段:当每一个存储型属性值被确定后,二阶段开始,它给每个类一次机会在新实例准备使用之前进一步定制它们的存储型属性。
两段式构造过程的使用让构造过程更安全,同时在整个类层级结构中给予了每个类完全的灵活性。
Swift 的两段式构造过程跟 Objective-C中的构造过程类似。最主要的区别在于阶段一,Objective-C给每一个属性赋值 0或空值(比如说 0或 nil)。Swift的构造流程则更加灵活,它允许你设置定制的初始值,并自如应对某些属性不能以 0或 nil作为合法默 认值的情况。
2.4 构造器的继承(概念)
与OC不同, Swift中子类不会默认继承父类的构造器.
(但如果满足以下2个条件会自动继承)
1)如果子类没有定义指定构造器, 那么他将主动继承父类的
2)如果子类提供了所有父类指定构造器的实现, 那么自动继承父类的便利构造器
- class Father{
- init(){
- println("father init")
- }
- convenience init(name:String){
- self.init();
- println("father convenience init")
- }
- }
- class Son:Father{
- override init(){ //子类实现了父类的全部指定构造器, 因而会自动继承父类的便利构造器
- println("son init")
- }
- }
- var son1 = Son()
- var son2 = Son(name: "xuneng") //自动继承了父类的便利构造器
2.5 通过闭包和函数来设置属性的默认值
- //闭包的一般格式
- class SomeClass{
- let someProperty : Int = { //整个花括号表示一个闭包
- return 0
- }() //这个小括号不能丢, 表示立即执行闭包. 并返回值.
- }
1)如果某个存储属性的值需要特别定制, 则可以使用闭包或全局函数类提供默认值.
2)当类型创建时, 闭包或函数会被调用,他们的返回值会被当做默认值赋值给这个存储属性.
3)使用闭包时, 实例的其他部分并没有初始化, 因而不能在闭包里面访问:其他实例属性/self属性/实例方法等.
- class Person6{
- let name : String = {//可以在闭包里面做一些复杂的初始化工作
- let firstName = "xu"
- let lastName = "neng"
- return firstName + lastName
- }()
- }
- var p6 = Person6()
- println(p6.name)
三、析构(反初始化) deinit
在一个类实例被释放之前, 反初始化函数被立即调用
Swift通过ARC来处理实例的内存管理, 与OC一样.
每个类只有一个反初始化函数, 不带任何参数. 且不允许主动调用.
子类继承了父类的反初始化函数(释放顺序类似Java. 先释放子类-->父类)
反初始化话方法能访问该实例的所有属性
- class Person7{
- var myMoney:Int
- init(){
- myMoney = 10
- }
- deinit{
- myMoney = 0 //可以访问类中的变量. 但这句没用. 因为销毁了,成员变量即不存在了
- //可以做一些清理工作
- }
【iOS】Swift类的继承、构造方法、析构器等复习的更多相关文章
- Swift—类的继承-备
Swift中的继承只能发生在类上,不能发生在枚举和结构体上.一个类可以继承另一个类的方法.属性.下标等特征,当一个类继承其他类时,继承类叫子类,被继承类叫父类(或超类).子类继承父类后,可以重写父类的 ...
- swift类、继承、接口
import Foundation class Hello{ var _name:String?="swift global" init(name:String){ //定义类中有 ...
- Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b
本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writ ...
- Swift 析构器deinit
析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标识,类似于构造器用init来标识. 原理: Swift会自动释放不再需要的实例以释放资源.Swift通 ...
- swift 学习- 17 -- 析构器
// 析构器 只适用与 类类型, 当一个类的实例被释放之前, 析构器会被立即调用, 析构器用关键字 deinit 来标示, 类似于构造器要用 init 来标示 // 析构过程原理 // Swift 会 ...
- Swift构造器(Initializer)与析构器(Deinitializer)
为了初始化结构体和类等类型的实例属性. 默认构造器 struct Fahrenheit { var temperature: Doubleinit(){ temperature = 32.0 } } ...
- Swift中子类必须包含的构造器和析构器
import Foundation /* Swift中子类必须包含的构造器 1.Swift允许在父类构造器前添加required关键字, 用于声明所有子类必须包含该required构造器 (如果没有声 ...
- 《从零开始学Swift》学习笔记(Day 41)——类的继承
原创文章,欢迎转载.转载请注明:关东升的博客 Swift中的继承只能发生在类上,不能发生在枚举和结构体上.一个类可以继承另一个类的方法.属性.下标等特征,当一个类继承其他类时,继承类叫子类,被继承类叫 ...
- 0604-面向对象、类与对象、类、static、构造方法/析构方法
一.面向对象 1.面向过程:一个人分步骤完成某个事情 2.面向对象:某件事情拆分为多个任务,由每个对象独立完成,最后调用整合为一个完整的项目 3.三要素:继承.封装.多态. 封装:私有化属性 提供公共 ...
随机推荐
- 关于transform的3D变形函数
继续transform的3D用法: translate3d(x,y,z)定义3D转换 transformX(x)只用x轴的值进行转换: transformY(y)只用y轴的值进行转换: transfo ...
- 【BZOJ2186】沙拉公主的困惑(数论)
[BZOJ2186]沙拉公主的困惑(数论) 题面 BZOJ 题解 考虑答案是啥 先假设\(n=m\) 现在求的就是\(\varphi(m!)\) 但是现在\(n!\)是\(m!\)的若干倍 我们知道 ...
- Luogu3444:[POI2006]ORK-Ploughing
题意 见luogu Sol 贪心+枚举 如果知道最后一次是消除一行 那么一定消了\(n\)行 此时只要消的列最小就好了 枚举每列从上往下消到哪里,那么下面消的越小越好 那么就有了贪心策略: 先消左右的 ...
- javascript使用闭包模拟私有属性和方法
最近因为做了一个项目,其中涉及到了js私有方法,这个概念在其语言里面是很常见的,很多语言都有private这个关键字,只要在一个类的前面加上private就表示申明了一个私有方法,但是javascri ...
- TP5模型关联问题
在使用模型关联时:假如有表 merchant商户表 m_store 店铺表 m_store_ref 商户店铺关联表 user 普通用户表 $mer = Merchant::with([ ' ...
- php 目录处理函数
之前我们处理的全都是文件,那目录和文件夹怎么处理呢? 我们就来学习目录或者称为文件夹的处理相关函数. 处理文件夹的基本思想如下: 1.读取某个路径的时候判断是否是文件夹 2.是文件夹的话,打开指定文件 ...
- angular路由模块(二)
上一章写的是如何创建一个简单的路由,这一样我们来看看如何创建一个路由模块.angular的思想就是(模块,组件,子组件.....). 我们在src/app目录下创建一个跟路由模块app-routing ...
- IDEA的配置
一.使用配置 转自:http://blog.csdn.net/qq_27093465/article/details/52918873 setting: 设置外观和字体: 设置编辑器快捷键: 自动 ...
- Java NIO FileVisitor 高效删除文件
在公司项目中,由于做个二维码扫码平台项目,预计每天产生的二维码图片达到十几G,所以要做个定时清理任务来定时清理图片,根据不同场景保留图片,规则是:1.二维码统一登录图片几个小时有效 2.电子名片二 ...
- c++cout执行顺序之一个不容易注意到的一点
二话不说,先看一个例子 #include <iostream> using namespace std; int main() { ]={,,,,,,,,,}; int *p=a; int ...