swift 继承和构造器

继承

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(width: 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 继承和构造器

时间: 2024-11-08 12:21:48

swift 继承和构造器的相关文章

swift 继承相关

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

swift基础学习(04)[运算符、属性、属性观察器、方法、下脚标本、继承、构造器]

//swift恒等运算符 //===恒等,不等!== //运用这两个运算符检测两个常量或者变量是否引用同一个实例 //"等价于"表示两个类类型(class type)的常量或者变量引用同一个类实例. //等于"表示两个实例的值"相等"或"相同",判定时要遵照设计者定义的评判标准,因此相对于"相 等"来说,这是一种更加合适的叫法. //类和结构体的选择 //属性的存储只能是类或者是结构体 //存储属性:变量存储属性va

swift继承与重载

一个类可以继承(inherit)另一个类的方法(methods),属性(property)和其它特性.当一个类继承其它类时,继承类叫子类(subclass),被继承类叫超类(或父类,superclass).在 Swift 中,继承是区分「类」与其它类型的一个基本特征. 在 Swift 中,类可以调用和访问超类的方法,属性和附属脚本(subscripts),并且可以重写(override)这些方法,属性和附属脚本来优化或修改它们的行为.Swift 会检查你的重写定义在超类中是否有匹配的定义,以此确

【Swift初见】Swift继承

对于继承这个名字大家应该都不陌生,在swift中也是一样,swift中的一个类可以继承另一个类的方法,属性和其他特性.当一个类继承其他类时,继承类叫做子类,被继承的类叫做父类,在swift中继承是区分类与其他类型的一个基本特征. 定义一个基类: 当一个类不继承其他类,这个类叫做基类.比如看下面的代码: class vehicle { var maxPassengers : Int var manufacturer : String func description() -> String{ re

Swift继承的用法

一个类可以继承另一个类的方法,属性和其它特性.当一个类继承其它类,继承类叫子类,被继承类叫超类(或父类).在Swift中,继承是区分「类」与其它类型的一个基本特征. 在Swift中,类可以调用和访问超类的方法,属性和下标,并且可以重写(override)这些方法,属性和下标来优化或修改它们的行为.Swift会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为是正确的. 可 以为类中继承来的属性添加属性观察器(property observer),这样一来,当属性值改变时,类就会被通知

【代码笔记】Java基础:类的继承(构造器)

在Java中,创建对象的格式为: 类名 对象名 = new 类名(): 如: 1 JFrame jf = new JFrame(); 一个对象被创建出来时,经常要先做一些事这个对象才能正常使用,也可以说是准备工作,比如给这个对象赋些初始值,或者先运行一些别的方法.这时候就需要一个“构造器”用于: 构造对象 初始化属性这样,把那些在创建时要做的事写在构造方法里,每次创建就会被执行一遍. 我们常见的一种Java格式: public 返回类型 方法名(参数){ } 如: 1 public void s

23.swift继承

import Foundation /* 继承语法 继承是面向对象最显著的一个特性, 继承是从已经有的类中派生出新的类 新的类能够继承已有类的属性和方法, 并能扩展新的能力 术语: 基类(父类, 超类), 派生类(子类, 继承类) 语法: class 子类: 父类{ } 继承有点: 代码重用 继承缺点: 增加程序耦合度, 父类改变会影响子类 注意:Swift和OC一样没有多继承 */ class Man { var name:String = "lnj" var age: Int =

学习Swift -- 继承

继承 一个类可以继承另一个类的方法(methods),属性(properties)和其它特性.当一个类继承其它类时,继承类叫子类,被继承类叫超类(父类). 在 Swift 中,子类可以调用和访问父类的方法,属性和下标脚本(subscripts),并且可以重写(override)这些方法.属性和下标脚本来优化或修改它们的行为.Swift 会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为是正确的. 可以为子类中继承来的属性添加属性观察器(property observers),这样一

Swift - 继承UIView实现自定义可视化组件(附记分牌样例)

在iOS开发中,如果创建一个自定义的组件通常可以通过继承UIView来实现.下面以一个记分牌组件为例,演示了组件的创建和使用,以及枚举.协议等相关知识的学习. 效果图如下: 组件代码:ScoreView.swift 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 5