swift 继承和构造器

摘要:
它以关键字init命名。StructFahrenheit{vartemperature:Doubleinit(){temperature=32.0}}构造函数不像函数和方法那样在括号前有可分辨名称。因此,在调用构造函数时,要调用的构造函数主要取决于构造函数中的参数名称和类型。这个过程称为构造函数代理,它可以减少多个构造函数之间的代码重复。即嵌套构造函数方法。对于值类型,可以使用self-Init引用自定义构造函数中具有相同值类型的其他构造函数。自动构造函数的继承如果子类没有定义任何指定的构造函数,它将自动继承所有父类的指定构造函数。

继承

class Vehicle {
    var numberOfWheels: Int
    var maxPassengers: Int
    func description() -> String {
        return "(numberOfWheels) wheels; up to (maxPassengers) passengers"
    }
    init() {
        numberOfWheels = 0
        maxPassengers = 1
    }
}

class Bicycle: Vehicle {
    init() {
        super.init()
        numberOfWheels = 2
    }
}

重写

如果要重写某个特性,你需要在重写定义的前面加上override关键字。这么做,你就表明了你是想提供一个重写版本,而非错误地提供了一个相同的定义。 你可以通过把方法,属性或下标脚本标记为final来防止它们被重写,只需要在声明关键字前加上@final特性即可。(例如:@final var, @final func, @final class func, 以及 @final subscript) 你可以通过在关键字class前添加@final特性(@final class)来将整个类标记为 final 的,这样的类是不可被继承的,否则会报编译错误。

  class Car: Vehicle {
    var speed: Double = 0.0
    init() {
        super.init()
        maxPassengers = 5
        numberOfWheels = 4
    }
    override func description() -> String {
        return super.description() + "; "
            + "traveling at (speed) mph"
    }

    override var speed: Double  {
    get {
        return super.speed
    }
    set {
        super.speed = min(newValue, 40.0)
    }
    }


     override var speed: Double {
    didSet {
        gear = Int(speed / 10.0) + 1
    }
    }
}

存储型属性的初始赋值

类和结构体在实例创建时,必须为所有存储型属性设置合适的初始值。存储型属性的值不能处于一个未知的状态。 当你为存储型属性设置默认值或者在构造器中为其赋值时,它们的值是被直接设置的,不会触发任何属性观测器(property observers)。

默认属性值 初始化属性

默认值将属性的初始化和属性的声明结合的更紧密。使用默认值能让你的构造器更简洁、更清晰,且能通过默认值自动推导出属性的类型;

  struct Fahrenheit {
    var temperature = 32.0
}

构造器 初始化属性

构造器在创建某特定类型的新实例时调用。以关键字init命名。

struct Fahrenheit {
    var temperature: Double
    init() {
        temperature = 32.0
    }
}

构造器并不像函数和方法那样在括号前有一个可辨别的名字。所以在调用构造器时,主要通过构造器中的参数名和类型来确定需要调用的构造器。
正因为参数如此重要,如果你在定义构造器时没有提供参数的外部名字,Swift 会为每个构造器的参数自动生成一个跟内部名字相同的外部名,就相当于在每个构造参数之前加了一个哈希符号。

  struct Celsius {
    var temperatureInCelsius: Double = 0.0
    init(fromFahrenheit fahrenheit: Double) {
        temperatureInCelsius = (fahrenheit - 32.0) / 1.8
    }
    init(fromKelvin kelvin: Double) {
        temperatureInCelsius = kelvin - 273.15
    }
}

只要在构造过程结束前常量的值能确定,你可以在构造过程中的任意时间点修改常量属性的值。
对某个类实例来说,它的常量属性只能在定义它的类的构造过程中修改;不能在子类中修改。

class SurveyQuestion {
    let text: String = "sss";
    var response: String?
    init(_ text: String) {
        self.text = text
    }
    func ask() {
        println(text)
    }
}
var a  = SurveyQuestion("dddd")
a.ask();

默认构造器

Swift 将为所有属性已提供默认值的且自身没有定义任何构造器的结构体或基类,提供一个默认的构造器

  class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()

逐一成员构造器---只针对结构体..类没有该构造器

如果结构体对所有存储型属性提供了默认值且自身没有提供定制的构造器,它们能自动获得一个逐一成员构造器。

struct Size {
    var width = 0.0, height = 0.0
}
let twoByTwo = Size( 2.0, height: 2.0)

如果你为某个值类型定义了一个定制的构造器,你将无法访问到默认构造器(如果是结构体,则无法访问逐一对象构造器)。这个限制可以防止你在为值类型定义了一个更复杂的,完成了重要准备构造器之后,别人还是错误的使用了那个自动生成的构造器。

构造器代理

构造器可以通过调用其它构造器来完成实例的部分构造过程。这一过程称为构造器代理,它能减少多个构造器间的代码重复。 就是嵌套构造器方法
对于值类型,你可以使用self.init在自定义的构造器中引用其它的属于相同值类型的构造器。并且你只能在构造器内部调用self.init。

struct Rect {
    var origin = Point()
    var size = Size()
    init() {}
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}

指定构造器和便利构造器

  • 指定构造器必须调用其直接父类的的指定构造器。
  • 便利构造器必须调用同一类中定义的其它构造器。
  • 便利构造器必须最终以调用一个指定构造器结束。

便利构造器需要在init关键字之前放置convenience关键字,并使用空格将它们俩分开:

  class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "[Unnamed]")
    }
}

与方法、属性和下标不同,在重载构造器时你没有必要使用关键字override。

如果你重载的构造器是一个指定构造器,你可以在子类里重载它的实现,并在自定义版本的构造器中调用父类版本的构造器。
如果你重载的构造器是一个便利构造器,你的重载过程必须通过调用同一类中提供的其它指定构造器来实现。

自动构造器的继承

  • 如果子类没有定义任何指定构造器,它将自动继承所有父类的指定构造器。
  • 如果子类提供了所有父类指定构造器的实现--不管是通过规则1继承过来的,还是通过自定义实现的--它将自动继承所有父类的便利构造器。

通过闭包和函数来设置属性的默认值

这种类型的闭包或函数一般会创建一个跟属性类型相同的临时变量,然后修改它的值以满足预期的初始状态,最后将这个临时变量的值作为属性的默认值进行返回。 注意闭包结尾的大括号后面接了一对空的小括号。这是用来告诉 Swift 需要立刻执行此闭包。如果你忽略了这对括号,相当于是将闭包本身作为值赋值给了属性,而不是将闭包的返回值赋值给属性。 如果你使用闭包来初始化属性的值,请记住在闭包执行时,实例的其它部分都还没有初始化。这意味着你不能够在闭包里访问其它的属性,就算这个属性有默认值也不允许。同样,你也不能使用隐式的self属性,或者调用其它的实例方法。 每当一个新的实例创建时,对应的赋值闭包会执行,

struct Checkerboard {
    let boardColors: Bool[] = {
        var temporaryBoard = Bool[]()
        var isBlack = false
        for i in 1...10 {
            for j in 1...10 {
                temporaryBoard.append(isBlack)
                isBlack = !isBlack
            }
            isBlack = !isBlack
        }
        return temporaryBoard
        }()
    func squareIsBlackAtRow(row: Int, column: Int) -> Bool {
        return boardColors[(row * 10) + column]
    }
}

免责声明:文章转载自《swift 继承和构造器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇java 关于JDBC和DAO模式使用Visual Studio 配置额外工具 Windows Terminal 等下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

11.Git分支-远程跟踪分支的概念、多个远程仓库的使用

1.远程跟踪分支的概念   远程引用是对远程仓库的引用,包括分支、标签等等。  1.可以通过 git ls-remote <remote> 来获得远程引用的完整列表  2.git remote show <remote> 来获取远程分支的更多相关信息。  如下图所示,运行 git remote show origin 可以得到有哪些...

不要再吹水地球人听不懂的技术,咱来点干货!中文前端UI框架Kit(一)大致了解下Kit是啥?

KitJs技术交流QQ高级群(可加500人) ,群号:88093625 Kitjs,(http://xueduany.github.com/KitJs),是我2011年底,离开淘宝UED之后,自己搞起的一套HTML5的前端widget库,原本的用途主攻手机端HTML页面交互组件使用,正如其字面意思Kit一样,愿景是做一个娇小,实用,既可以直接拿来用,也可以...

如何使用 Workman 做一个聊天室

一:首先,得简单说说 thinkphp+workerman 的安装。 安装 thinkphp5.1 composer create-project topthink/think=5.1.x-dev tp5andworkman 安装 think-worker 我的官方群点击此处。 composer require workerman/workerman 二:...

git rebase简介(基本篇)

原文: http://gitbook.liuhui998.com/4_2.html 一、基本 git rebase用于把一个分支的修改合并到当前分支。 假设你现在基于远程分支"origin",创建一个叫"mywork"的分支。 $ git checkout -b mywork origin 假设远程分支"origin"已经有了2个提交,如图   现在...

深入单例模式

单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好、用对单例模式,还真得费一番脑筋。本文对Java中常见的单例模式写法做了一个总结,如有错漏之处,恳请读者指正。 饿汉法 顾名思义,饿汉法就是在第一次引用该类的时候就创建对象实例,而不管实际是否需要创建。代码如下: public class Singleton { private...

git 的安装以及使用:是一个开源的分布式版本控制系统,可以对项目进行版本管理。 早期是linux之父用来管理linux系统源代码的(linux是和windows一样操作系统 开源免费的操作

## 总结 - 学会使用基本的git命令 管理源代码- 学会去github创建仓库 并将代码上传到github的仓库 (有待完成 回家有网再push)- 了解本地的.git和服务器github的.git的关系 是两个仓库 一个是本地 一个是服务器 需要使用一句命令来关联 git remote add origin 远端的.git的地址- 了解github的...