【iOS】Swift类的继承、构造方法、析构器等复习

构造方法内容会多一些,涉及Swift中构造的一些规则与概念。这次写了7个Person来复习,外加名人XiaoMing。

Mark:Playground真是个好东西,特别练习写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   //可以访问类中的变量. 但这句没用. 因为销毁了,成员变量即不存在了
        //可以做一些清理工作
    }
}

var p:Person7? = Person7()
println(p!.myMoney)
p = nil   //可选类型才能设置为nil
//p!.myMoney   //错误, 已设置为nil

参考:

The Swift Programming Language  

Apple Dev Center

转载请注明出处:http://blog.csdn.net/xn4545945  

时间: 2024-12-28 21:01:59

【iOS】Swift类的继承、构造方法、析构器等复习的相关文章

swift类、继承、接口

import Foundation class Hello{ var _name:String?="swift global" init(name:String){ //定义类中有参数的构造方法 _name=name; println("Hello , \(name)"); } init(){ //定义类中无参数的构造方法 println("this is init method"); } func sayHello(){ //定义成员方法 pr

十四、析构器 Deinitialization

1. 当一个实例被释放(deallocated)时,析构器会立即被调用.使用关键字 deinit 来定义析构器.只有类类型才有析构器. 2. 析构器工作原理 How Deinitialization Works 当一个实例的自动引用计数 Automatic Reference Counting 为0时,Swift会释放这个实例.一般情况下,当一个实例被dealloc时,释放资源的工作都有Swift完成,但是某些时候,你需要自己进行一些释放资源的工作,比如你创建一个类执行打开文件操作,并写数据到文

Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b

本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writing Initializers and Deinitializers) 集成Interface Builder(Integrating with Interface Builder) 指明属性特性(Specifying Property Attributes) 实现Core Data Manage

14 PHP 类的继承 [public protected private] parent 构造方法 析构方法 重写 最终类和方法 设计模式

类的继承 简单理解: 某个类A具有某些特征,另一个类B,也具有A类的所有特征,并且还可能具有自己的更多的一些特征,此时,我们就可以实现:B类使用A的特征信息并继续添加自己的一些特有特征信息. 基本概念 继承:一个类从另一个已有的类获得其特性,称为继承. 派生:从一个已有的类产生一个新的类,称为派生. 继承和派生,其实只是从不同的方向(角度)来表述,本质上就是一个事情. 父类/子类:已有类为父类,新建类为子类.父类也叫"基类",子类也叫"派生类" 单继承:一个类只能从

Swift:面向对象(继承与构造方法)

一. 继承 1.  Swift中定义的类,如果不继承自任何类,它就是基类.这一点和objective-c中定义的类不一样,在objective-c中定义的类默认的基类是NSObject. 2.  重写父类的方法及属性,必须使用override的关键字(这样处理的话,更清晰了,很容易看出是父类的方法还是自己类中的方法). 3.  如果在类,方法,属性 前面用final进行了修饰,就不允许被继承或者被重写. 类继承关系Demo: class Animal { var speed : Int = 1

IOS开发语言Swift入门连载---继承

IOS开发语言Swift入门连载-继承 一个类可以继承(inherit)另一个类的方法(methods),属性(property)和其它特性.当一个类继承其它类时,继承类叫子类(subclass),被继承类叫超类(或父类,superclass).在 Swift 中,继承是区分「类」与其它类型的一个基本特征. 在 Swift 中,类可以调用和访问超类的方法,属性和下标脚本(subscripts),并且可以重写(override)这些方法,属性和下标脚本来优化或修改它们的行为.Swift 会检查你的

Swift构造器(Initializer)与析构器(Deinitializer)

为了初始化结构体和类等类型的实例属性. 默认构造器 [html] view plaincopy struct Fahrenheit { var temperature: Doubleinit(){ temperature = 32.0 } } var f = Fahrenheit() //调用默认构造器 init() ,没有参数 没有返回值. [html] view plaincopy println("The default temperature   is \(f.temperature)°

《从零开始学Swift》学习笔记(Day 41)——类的继承

原创文章,欢迎转载.转载请注明:关东升的博客 Swift中的继承只能发生在类上,不能发生在枚举和结构体上.一个类可以继承另一个类的方法.属性.下标等特征,当一个类继承其他类时,继承类叫子类,被继承类叫父类(或超类).子类继承父类后,可以重写父类的方法.属性.下标等特征. 为了了解继承性,看这样一个场景:一位面向对象的程序员小赵,在编程过程中需要描述和处理个人信息,于是他定义了类Person,如下所示: class Person {     var name: String     var age

c++第五章-(类与对象、构造器和析构器)

1.构造器与结构体的区别:构造器多支持方法.其作用有申请内存,初始化变量. 在c++中构造器没有返回值:语法Class Name(); 2.析构器的作用:释放内存. 在c++中析构器没有返回值:语法~ClassName(); class Animal { public: std::string mouth; std::string name; void eat(); void sleep(); void drool(); Animal(std::string theName); }; class