swift 学习- 14 -- 继承
// 一个类可以继承另一个 类的方法, 属性和其他特征, 当一个类继承其他类时, 继承类叫子类, 被继承类叫父类 或 (超类), 在 Swift 中, 继承是区分 [类] 和其他类型的 一个基本特征
// 在 Swift 中, 类可以调用和访问超类的方法, 属性 和 下标, 并且可以重写这些方法, 属性 和 下标来优化或修改他们的行为
// Swift 会检查你的重写定义在超类中是否有匹配的定义, 一次确保你的重写行为是正确的
// 可以为类中继承来的属性添加属性观察器, 这样一来, 当属性值改变时, 类就会被通知到, 可以为 任意属性 添加 属性观察器,无论他原本被定义为 存储属性 还是 计算属性
// 定义一个基类
// 不继承于其他类的类, 称之为 基类
// 注意 : Swift 中的类并不是 从一个通用的 基类继承而来, 如果你不为你定义的类指定一个 超类 的话, 这个类就自动成为 基类
// 一个例子定义了一个叫做 Vehicle 的基类, 这个基类声明了一个名为 currentSpeed , 默认值是 0.0 的存储属性 (属性类型推断为 Double), currentSpeed 属性的值被一个 String 类型的只读计算型属性 description 使用, 用来创建车辆的描述 . Vehicle 基类也定义了一个名为 makeNoise 的方法, 这个方法实际上部位 Vehicle 实例做任何事, 但之后将会被 Vehicle 的子类定制
class Vehicle{
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// 什么也不作
}
}
let someVehicle = Vehicle()
print("Vehicle: \(someVehicle.description)")
// 子类生成
// 子类生成 指的是在一个已有类的基础上创建一个新的类, 子类继承超类的特性, 并且可以进一步完善, 你还可以为子类添加新的特性
// 为了指明某个类的超类, 将超类名卸载子类名的后面, 用冒号分割:
class Bicycle: Vehicle{
var hasBasket = false
}
// 新的 Bicycle 类自动获得 Vehicle 类的所有属性 和 方法, 除了他所继承的特性, Bicycle 类还定义了一个默认值为 false 的存储属性 hasBasket (Bool 型)
// 默认情况下,你创建的任何新的 Bicycle 实例将不会有一个篮子,但是可以为特定的 Bicycle 实例设置 hasBasket 属性为 ture
let bicycle = Bicycle()
bicycle.hasBasket = true
// 还可以修改 Bicycle 实例所继承的 currentSpeed 属性, 和查询实例所继承的 descriotion 属性:
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.currentSpeed)")
// 子类还可以继续被其它类所继承 下面的示例为Bicycle创建了一个名为Tandem(双人自行车)的子类:
class Tandem: Bicycle {
var currentNumberOfPassengers = 0
}
// Tandem从Bicycle继承了所有的属性与方法,这又使它同时继承了Vehicle的所有属性与方法。Tandem也增加了一个新的叫做currentNumberOfPassengers的存储型属性,默认值为0。
// 如果你创建了一个Tandem的实例,你可以使用它所有的新属性和继承的属性,还能查询从Vehicle继承来的只读属性description:
let tandem = Tandem()
tandem.hasBasket = true
tandem.currentNumberOfPassengers = 2
tandem.currentSpeed = 22.0
print("Tandem: \(tandem.description)")
// 打印:"Tandem: traveling at 22.0 miles per hour"
// 重写
// 子类可以为继承来的实例方法, 类方法, 实例属性, 或 下标提供自己定制实现, 我们把这种行为叫做 重写
// 如果要重写某个特性, 你需要在重写定义的前面加上 override 关键字, 这么做, 你就表明了你是想提供一个重写版本, 而非错误地提供一个相同的定义, 意外的重写可能导致 不可预知的 错误, 任何缺少 override 关键字的 重写都会在编译时诊断为 错误
// override 关键字会提醒 Swift 编辑器去检查该类的 超类,是否有匹配重写版本的声明, 这个检查可以确保你的重写定义是正确的
// 访问超类的方法, 属性 和 下标
// 当你在子类中重写超类的方法,属性 或 下标时, 有时 在你的重写版本中 使用已经存在的 超类实现 会大有裨益, 比如, 你完全可以完善已有实现的行为, 或在一个继承来的变量中存储一个修改过的值
// 在适当的地方, 你可以通过使用 super 前缀来访问超类版本的方法, 属性 或 下标
// 1: 在方法someMethod()的重写实现中,可以通过super.someMethod()来调用超类版本的someMethod()方法。
// 2: 在属性someProperty的 getter 或 setter 的重写实现中,可以通过super.someProperty来访问超类版本的someProperty属性。
// 3: 在下标的重写实现中,可以通过super[someIndex]来访问超类版本中的相同下标。
// 重写方法
// 在子类中, 你可以重写继承来的实例方法或类方法, 提供一个定制或替代的方法实现
class Train: Vehicle{
override func makeNoise() {
print("Choo Choo")
}
}
// 这个例子定义了 Vehicle 的一个新的子类, 叫 Train, 它重写了从 Vehicle 类继承来的 makeNoise() 方法
let train = Train()
train.makeNoise()
// 重写属性
// 你可以重写继承来的实例属性或类型属性, 提供自己定制的 getter 和 setter,或添加属性观察器 使 重写的属性 也可以观察值什么时候变化
// 重写 属性的 getter 和 setter
// 你可以提供定制的 getter 和 setter 来重写任意继承来的属性, 无论继承来的属性是存储型的 还是 计算型属性, 子类并不知道继承来的属性是 存储型的 还是 计算型的, 它只知道继承来的属性会有一个 名字和类型 , 你在重写一个属性时, 必须将它的 名字和类型 都写出来, 这样才能使编译器 去检查你重写的属性 是否与 超类中同名同类型的属性 相匹配的
// 你可以将一个继承来的 只读属性 重写为 读写属性,只需要在重写版本的属性里 提供 getter 和 setter 即可, 但是,你不能将一个继承来的读写属性 重写为 一个只读属性
// 注意 : 如果你在重写属性中提供了 setter ,那么你也一定要提供 getter, 如果你不想在重写版本中的 getter 里修改继承来的属性值, 你可以直接通过 super.someProperty 来返回继承来的值, 其中 someProperty 是你要重写的属性的名字
class Car: Vehicle{
var gear = 1
override var description: String{
return super.description + " in gear \(gear)"
}
}
// 这个例子定义了一个新类,叫Car,它是Vehicle的子类。这个类引入了一个新的存储型属性叫做gear,默认值为整数1。Car类重写了继承自Vehicle的description属性,提供包含当前档位的自定义描述:
// 重写的 description 属性首先要调用 super.description 返回 Vehicle 类的 description 属性 之后, Car 类版本的 description 在末尾增加了自定义内容
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")
// 重写属性观察器
// 你可以通过重写属性为一个 继承来的 属性 添加 属性观察器, 这样一来, 当继承来的属性值发生变化时, 你就会被通知到, 无论哪个属性原本是如何实现的
// 注意 : 你不可以为继承来的常量存储属性 或 继承来的只读计算属性添加 属性观察器, 这些属性的值是不可以被设置的. 所以, 为他们提供 willSet 和 didSet 是不恰当的
// 此外, 你不可以同时提供重写的 setter 和 重写的 属性观察器, 如果你想观察属性值的变化, 并且你已经为那个属性提供了定制的 setter ,那么你在 setter 中就可以观察到任何值的变化了
class AutomaticCar: Car{
override var currentSpeed: Double{
didSet{
gear = Int(currentSpeed / 10.0) + 1
}
}
}
// 当你设置 AutomaticCar 的 currentSprrd 属性, 属性的 didSet 观察器就会自动地设置 gear 属性, 为新的速度选择一个合适的档位, 具体来说, 属性观察器将新的速度值除以 10 ,然后向下取得最接近的整数值, 最后加 1 来得到档位 gear 的值,
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar: \(automatic.description)")
// 防止重写
// 你可以通过把方法,属性 或 下标标记为 final 来防止他们被重写, 只需要在声明关键字前 加上 final 修饰符即可
// 如 : final var , final func, final class func , final subscript
// 如果你重写了带有 final 标记的方法, 属性或者下标, 在编译时或报错,
// 在类扩展中的方法, 属性 或 下标也可以在扩展的定义里标记为 fnial
// 你可以通过在关键字 class 前添加 final 修饰符 (final class) 来将整个类标记为 final 的, 这样的类是不可被继承的, 试图继承这样的类会导致编译错误
swift 学习- 14 -- 继承的更多相关文章
- Swift 学习笔记 (继承)
一个类可以从另一个类继承方法.属性和其他的特性.当一个类从另一个类继承的时候,继承的类就是所谓的子类,而这个类继承的类被称为父类. 在 Swift 中类可以调用和访问属于它们父类的方法.属性和下标脚本 ...
- C++学习14 继承的概念及语法
继承是类与类之间的关系,是一个很简单很直观的概念,与现实世界中的继承(例如儿子继承父亲财产)类似. 继承(Inheritance)可以理解为一个类从另一个类获取成员变量和成员函数的过程.例如类B继承于 ...
- Swift学习——类的定义,使用,继承,构造等(五)
Swift学习--类的定义,使用.继承,构造等(五) 类的使用说明 1 使用class和类名来创建一个类名,比如: class student 2 类中属性的声明和常量和变量一样,唯一的差别就是他们的 ...
- 【Swift学习】Swift编程之旅---继承(十七)
在 Swift 中,继承是区分「类」与其它类型的一个基本特征.swift不支持多重继承.类可以调用和访问超类的方法,属性和subscripts下标,并且可以重写(override)这些方法,属性和附属 ...
- swift学习笔记之-继承
//继承 import UIKit /* 继承(Inheritance): 1.一个类可以继承(inherit)另一个类的方法(methods).属性(properties)和其它特性.当一个类继承其 ...
- swift学习笔记(四)关于类的继承
在swift中,继承是区分类与其它对象的基本特征 继承后的子类能够重写父类的方法,包含类方法和实例方法,属性和附属脚本(subscript) 在继承过程中,构造器方法init()是不被继承的,须要显示 ...
- Swift学习目录
本学习基于苹果官方Swift学习材料,保留了原版90%左右的内容(一些项目开发中基本不用的知识点没有整理),并根据理解进行整理.如对原版感兴趣,可以直接单击链接阅读和学习. 第一部分 基础篇 1.基本 ...
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习之常用UI的使用
Swift学习之常用UI的使用 最近笔者在开始学习苹果最新的编程语言,因为笔者认为,苹果既然出了这门语言就绝对不会放弃,除非苹果倒闭了(当然这里知识一个玩笑). 所以在不久的将来,swift绝对是iO ...
随机推荐
- WebSocket 快速开始
[Html5客户端API] 1.创建websocket对象 var connection = new WebSocket('ws[s]://www.example.com/chat',可选自己实现的 ...
- python发送网络请求
1.使用urllib模块(使用不方便,建议使用第二种) get请求: res = urlopen(url) from urllib.request import urlopen url = 'http ...
- Python之List列表的增删改查
序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列 ...
- 在eclipse中从cvs下载项目,再部署到tomcat常见错误!
1.先调出cvs视图 如果cvs插件还未安装,下载一个: 安装cvs插件:将features和pluguns文件夹里面的内容分别复制到eclipse安装路径下面对应的features和pluguns文 ...
- 数组去重的4种方法(Which one is the fastest???嘻嘻嘻....)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- C - CodeCoder vs TopForces Gym - 101142C (连通块+思维)
题目链接: C - CodeCoder vs TopForces Gym - 101142C 题目大意:给你n个人的信息,每一个人的信息包括两个.t1和t2.A>B的前提是A的t1和t2至少有一 ...
- 简单日历dom
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title> ...
- openstack Q版部署-----虚拟机创建(8)
一 .创建网络环境 环境变量生效一下 创建一个网络: openstack network create --share --external \ --provider-physical-network ...
- QR二维码原理(一)
一.什么是QR码 QR码属于矩阵式二维码中的一个种类,由DENSO(日本电装)公司开发,由JIS和ISO将其标准化.QR码的样子其实在很多场合已经能够被看到了,我这还是贴个图展示一下: 这个图如果被正 ...
- Python学习笔记-随机数
IronPython的random 只能在0-0.5之间,所以最后调用了C#的Random. #!/usr/bin/python #coding=utf-8 import random import ...