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 继承和构造器的更多相关文章
- Java继承中构造器的调用原理
Java的继承是比较重要的特性,也是比较容易出错的地方,下面这个例子将展示如果父类构造器中调用被子类重写的方法时会出现的情况: 首先是父类: public class test { void fun( ...
- Swift—继承
一个类可以继承另一个类的方法,属性和其他特性.当一个类继承其他类时,继承类叫子类,被继承类叫超类(或父类).在Swift中,继承具有单继承的特点,每个子类只有一个直接父类,继承是区分类与其他类型的一个 ...
- 学习Swift -- 继承
继承 一个类可以继承另一个类的方法(methods),属性(properties)和其它特性.当一个类继承其它类时,继承类叫子类,被继承类叫超类(父类). 在 Swift 中,子类可以调用和访问父类的 ...
- Swift: 继承
为了在属性值改变的时候获得通知,类可以为继承的属性添加属性观察者.属性观察者可以添加到任何属性上,不管这个属性原来是存储属性还是计算属性. Swift中的类没有一个统一的基类. 为了讲明白继承,我们先 ...
- Swift继承的用法
一个类可以继承另一个类的方法,属性和其它特性.当一个类继承其它类,继承类叫子类,被继承类叫超类(或父类).在Swift中,继承是区分「类」与其它类型的一个基本特征. 在Swift中,类可以调用和访问超 ...
- Swift - 继承UIView实现自定义可视化组件(附记分牌样例)
在iOS开发中,如果创建一个自定义的组件通常可以通过继承UIView来实现.下面以一个记分牌组件为例,演示了组件的创建和使用,以及枚举.协议等相关知识的学习. 效果图如下: 组件代码:Score ...
- 【代码笔记】Java基础:类的继承(构造器)
在Java中,创建对象的格式为: 类名 对象名 = new 类名(): 如: 1 JFrame jf = new JFrame(); 一个对象被创建出来时,经常要先做一些事这个对象才能正常使用,也可以 ...
- Swift继承
//声明一个基类 class vehicle { var maxPassenger : Int = 0 var manufacturer : String! func description() -& ...
- Swift构造器重载
与函数一样,方法也存在重载,其重载的方式与函数一致.那么作为构造器的特殊方法,是否也存在重载呢?答案是肯定的.一.构造器重载概念Swift中函数重载的条件也适用于构造器,条件如下:函数有相同的名字:参 ...
随机推荐
- mysql求交集:UNION ALL合并查询,inner join内连接查询,IN/EXISTS子查询
两个要求交集的表(列)的结构要一致,对应的字段数,字段类型都应该相同:将两个数据的数据列用 UNION ALL 关键字合并:将上面的所有需要比较的列 GROUP BY :最后 HAVING COUNT ...
- SQL中truncate table和delete的区别
truncate table table_name delete from table_name drop table table_name truncate table在功能上与不带where子句的 ...
- Orchard运用 - 定制博客分页显示
一般,对于条目过多的系统或博客,分页显示是最简单的方式.目前分页方式基本有三种格式: 1.显示所有信息,包括标明当前页面,提供上一页和下一页链接和使用首页和末页链接. 2.只标注上一页和下一页链接. ...
- dede 怎样调用其它栏目的文章或者缩略图列表且有分页效果?
提问i:我做一个站点.有5个栏目,第5个栏目想把前4个栏目的文章都调用一下,搞一个汇总的文章集合. 发现用arclist调用不能设置pagesize的属性.从而不能给文章分页.然而list貌似不能调用 ...
- T-SQL 之 语法元素
一.标识符 在T-SQL语言中,对SQLServer数据库及其数据对象(比如表.索引.视图.存储过程.触发器等)需要以名称来进行命名并加以区分,这些名称就称为标识符. 通常情况下,SQLServer数 ...
- DoxygenToolkit.vim
DoxygenToolkit.vim 常用命令: 光标在函数上,用 :Dox 自动生成函数的说明. 光标在文件头,用 :DoxAthor 自动生成文件说明. 下载地址
- CLR_Via_C#学习笔记之CLR的执行模型
1:公共语言运行时(Common Language Runtime,CLR)是一个可由多种编程语言使用的“运行时”.CLR的核心功能(比如内存管理.程序集加载.安全性.异常处理和线程同步)可由面向CL ...
- hadoop 异常及处理总结-02(小马哥精品)
一直以来,对hdfs的警告信息不报以理睬,今天突然关注了一下.每当我操作hdfs的时候就会出现这样一个警告: WARN util.NativeCodeLoader: Unable to load na ...
- Warning: cast to/from pointer from/to integer of different size
将int变量转为(void*)时出现错误 error: cast to pointer from integer of different size [-Werror=int-to-pointer-c ...
- myDate97用法
myDate97用法 CreateTime--2017年5月12日11:00:32Author:Marydon 一.基本用法 官网链接:http://www.my97.net/index.asp ...