前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Swift基础 继承

Swift基础 继承

作者头像
郭顺发
发布于 2023-07-17 09:12:42
发布于 2023-07-17 09:12:42
1300
举报
文章被收录于专栏:pandacode_cnpandacode_cn

Swift基础 - 继承

翻译自:https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html

一个类可以从另一个类继承方法、属性和其他特征。当一个类从另一个类继承时,继承类被称为子类,它继承的类被称为其超类。继承是一种基本行为,可以将类与 Swift 中的其他类型区分开来。

Swift中的类可以调用和访问属于其超类的方法、属性和下标,并可以提供这些方法、属性和下标的覆盖版本,以细化或修改其行为。Swift通过检查覆盖定义是否具有匹配的超类定义来帮助确保您的覆盖正确。

类还可以将属性观察者添加到继承的属性中,以便在属性值发生变化时收到通知。属性观察者可以添加到任何属性中,无论它最初是否被定义为存储或计算属性。

定义基类

任何不从另一个类继承的类都被称为基类

注意

Swift类不会从通用基类继承。您在不指定超类的情况下定义的类会自动成为供您构建的基类。

下面的示例定义了一个名为Vehicle的基类。该基类定义了一个名为currentSpeed存储属性,默认值为0.0(推断Double的属性类型)。currentSpeed属性的值被称为description的只读计算String属性用于创建车辆的描述。

Vehicle基类还定义了一个名为makeNoise的方法。此方法实际上对基本Vehicle实例不起作用,但稍后将由Vehicle子类自定义:

  1. class Vehicle {
  2. ​ var currentSpeed = 0.0
  3. ​ var description: String {
  4. ​ return “traveling at (currentSpeed) miles per hour”
  5. ​ }
  6. ​ func makeNoise() {
  7. ​ // do nothing - an arbitrary vehicle doesn’t necessarily make a noise
  8. ​ }
  9. }

您创建一个带有初始化器语法的新Vehicle实例,该语法写为类型名称,后跟空括号:

  1. let someVehicle = Vehicle()

创建新的Vehicle实例后,您可以访问其description属性,以打印车辆当前速度的人类可读描述:

  1. print(“Vehicle: (someVehicle.description)”)
  2. // Vehicle: traveling at 0.0 miles per hour

Vehicle类定义了任意车辆的常见特征,但其本身没有多大用处。为了使其更有用,您需要对其进行细化,以描述更具体的车辆类型。

子分类

子类是将新类建立在现有类的基础上的行为。子类继承了现有类的特征,然后您可以对其进行细化。您还可以为子类添加新特征。

要指示子类有一个超类,请在超类名称之前写下子类名称,用冒号分隔:

  1. class SomeSubclass: SomeSuperclass {
  2. ​ // subclass definition goes here
  3. }

以下示例定义了一个名为Bicycle的子类,具有超类Vehicle

  1. class Bicycle: Vehicle {
  2. ​ var hasBasket = false
  3. }

新的Bicycle类会自动获得Vehicle的所有特征,例如其currentSpeeddescription属性及其makeNoise()方法。

除了继承的特征外,Bicycle类还定义了一个新的存储属性hasBasket,默认值为false(为该属性推断一种Bool类型)。

默认情况下,您创建的任何新Bicycle实例都不会有篮子。创建特定Bicycle实例后,您可以将该实例的hasBasket属性设置为true

  1. let bicycle = Bicycle()
  2. bicycle.hasBasket = true

您还可以修改Bicycle实例的继承的currentSpeed属性,并查询实例的继承description属性:

  1. bicycle.currentSpeed = 15.0
  2. print(“Bicycle: (bicycle.description)”)
  3. // Bicycle: traveling at 15.0 miles per hour

子类本身可以被子类。下一个示例为被称为“串联”的双座自行车创建Bicycle子类:

  1. class Tandem: Bicycle {
  2. ​ var currentNumberOfPassengers = 0
  3. }

Tandem inherits all of the properties and methods from Bicycle, which in turn inherits all of the properties and methods from Vehicle. The Tandem subclass also adds a new stored property called currentNumberOfPassengers, with a default value of 0.

如果您创建Tandem实例,您可以处理其任何新的和继承的属性,并查询它从Vehicle继承的只读description属性:

  1. let tandem = Tandem()
  2. tandem.hasBasket = true
  3. tandem.currentNumberOfPassengers = 2
  4. tandem.currentSpeed = 22.0
  5. print(“Tandem: (tandem.description)”)
  6. // Tandem: traveling at 22.0 miles per hour

压倒一切的

子类可以提供实例方法、类型方法、实例属性、类型属性或下标的自定义实现,否则它将从超类继承。这被称为压倒一切

要覆盖否则会继承的特征,请在覆盖定义前加上override关键字。这样做会澄清您打算提供重写,并且没有错误地提供匹配的定义。意外覆盖可能会导致意外行为,任何没有override关键字的覆盖都会在编译代码时被诊断为错误。

override关键字还会提示Swift编译器检查重写类的超类(或其父类之一)的声明是否与您为重写提供的声明相匹配。此检查可确保您的重写定义正确无误。

访问超类方法、属性和下标

当您为子类提供方法、属性或下标覆盖时,有时使用现有的超类实现作为重写的一部分非常有用。例如,您可以细化该现有实现的行为,或将修改后的值存储在现有继承的变量中。

在适当的情况下,您可以使用super前缀访问方法、属性或下标的超类版本:

  • 名为someMethod()重写方法可以通过在重写方法实现中调用super.someMethod()来调用someMethod()的超类版本。
  • 名为someProperty的重写属性可以在重写getter或setter实现中以super.someProperty的形式访问someProperty的超类版本。
  • someIndex的重写下标可以从重写下标实现中访问与super[someIndex]相同的下标的超类版本。

压倒一切的方法

您可以重写继承的实例或类型方法,以便在子类中提供方法的定制或替代实现。

以下示例定义了一个名为Train的新Vehicle子类,该子类覆盖了TrainVehicle继承的makeNoise()方法:

  1. class Train: Vehicle {
  2. ​ override func makeNoise() {
  3. ​ print(“Choo Choo”)
  4. ​ }
  5. }

如果您创建一个新的Train实例并调用其makeNoise()方法,您可以看到该方法的Train子类版本被调用:

  1. let train = Train()
  2. train.makeNoise()
  3. // Prints “Choo Choo”

压倒一切的属性

您可以重写继承的实例或类型属性,为该属性提供自己的自定义获取器和设置器,或添加属性观察器,以使重写属性能够观察基础属性值何时更改。

压倒一切的财产获取者和设定者

您可以提供自定义获取器(如果适用,并酌情提供设置器)来覆盖任何继承的属性,无论继承的属性是在源代码中实现为存储的还是计算属性。子类不知道继承属性的存储或计算性质——它只知道继承属性具有特定的名称和类型。您必须始终声明要重写的属性的名称和类型,以使编译器能够检查您的重写是否与具有相同名称和类型的超类属性匹配。

您可以通过在子类属性重写中同时提供获取器和设置器来将继承的只读属性呈现为读写属性。但是,您不能将继承的读写属性显示为只读属性。

注意

如果您提供设置器作为属性覆盖的一部分,您还必须为该覆盖提供获取器。如果您不想在覆盖getter中修改继承属性的值,只需从getter返回super.someProperty来传递继承的值,其中someProperty是您要重写的属性的名称。

以下示例定义了一个名为Car的新类,这是Vehicle的一个子类。TheCar类引入了一个新的存储属性,称为gear,默认整数值为1。TheCar类还覆盖了它从Vehicle继承的description属性,以提供包含当前齿轮的自定义描述:

  1. class Car: Vehicle {
  2. ​ var gear = 1
  3. ​ override var description: String {
  4. ​ return super.description + “ in gear (gear)”
  5. ​ }
  6. }

The override of the description property starts by calling super.description, which returns the Vehicle class’s description property. The Car class’s version of descriptionthen adds some extra text onto the end of this description to provide information about the current gear.

如果您创建Car类的实例并设置其gearcurrentSpeed属性,您可以看到它的description属性返回在Car类中定义的定制描述:

  1. let car = Car()
  2. car.currentSpeed = 25.0
  3. car.gear = 3
  4. print(“Car: (car.description)”)
  5. // Car: traveling at 25.0 miles per hour in gear 3
压倒一切的财产观察者

您可以使用属性重写将属性观察者添加到继承的属性中。这使您能够在继承属性的值发生变化时收到通知,无论该属性最初是如何实现的。有关财产观察员的更多信息,请参阅财产观察员

注意

您无法将属性观察者添加到继承的常量存储属性或继承的只读计算属性。无法设置这些属性的值,因此不宜提供将willSetdidSet实现作为重写的一部分。

另请注意,您无法同时提供同一属性的重写设置器和重写属性观察器。如果您想观察属性值的变化,并且您已经在为该属性提供自定义设置器,您可以简单地从自定义设置器中观察任何值更改。

以下示例定义了一个名为AutomaticCar的新类,这是Car的一个子类。AutomaticCar类表示带有自动变速箱的汽车,该变速箱根据当前速度自动选择要使用的适当齿轮:

  1. class AutomaticCar: Car {
  2. ​ override var currentSpeed: Double {
  3. ​ didSet {
  4. ​ gear = Int(currentSpeed / 10.0) + 1
  5. ​ }
  6. ​ }
  7. }

每当您设置AutomaticCar实例的currentSpeed属性时,该属性的sdidSet观察器都会将实例的gear属性设置为新速度的适当齿轮选择。具体来说,属性观察者选择一个新的currentSpeed值除以10的齿轮,四舍五入到最近的整数,加上1。35.0的速度产生4的齿轮:

  1. let automatic = AutomaticCar()
  2. automatic.currentSpeed = 35.0
  3. print(“AutomaticCar: (automatic.description)”)
  4. // AutomaticCar: traveling at 35.0 miles per hour in gear 4

防止重写

You can prevent a method, property, or subscript from being overridden by marking it as final. Do this by writing the final modifier before the method, property, or subscript’s introducer keyword (such as final var, final func, final class func, and final subscript).

任何在子类中重写最终方法、属性或下标的尝试都将报告为编译时错误。您添加到扩展类的方法、属性或下标也可以在扩展的定义中标记为最终。

您可以通过在类定义(finalclass)中的class关键字之前编写final修饰符,将整个类标记为最终修饰语。任何对最终类进行子类的尝试都将报告为编译时错误。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Swift2.1-继承继承
一个类可以从另一个类继承方法,属性和其他的特性。当一个类从另一个类继承的时候,继承类被称为子类,这个类继承的类被称为父类。在Swift中,继承是基本的,从Swift中的其他类型来区分类的一种行为。
hrscy
2018/08/30
4690
Swift专题讲解十四——继承 原
        Swift中,一个类可以从另一个类继承方法、属性、下标及其他特性。当一个类继承于另一个类时,这个类被称为子类,所继承的类被称为父类。在Swift中,继承是类区别于其他类型的主要特征。子类除了可以调用父类的属性,下标,方法外,其也可以对父类的属性,下标,方法进行覆写。
珲少
2018/08/15
2890
17.Swift学习之类
类的介绍和定义 Swift虽然推荐面向协议编程,但其也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定义类呢? Swift中用class关键字定义类 定义语法 cla
YungFan
2018/11/07
6180
Swift基础 初始化
翻译自:https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
郭顺发
2023/07/17
1950
Swift3.0 - 对象和类
1.对象中的所有变量或者常量在定义时如果不初始化,在对象初始化的时候,必须初始化,这个是swift安全性考虑,可选类型没有强制性要求初始化,因为系统默认给可选类型初始化为nil
酷走天涯
2018/09/14
4280
swift 继承
这样子类将无法重写dosomething方法,编译器提示错误为Instance method overrides a 'final' instance method
xy_ss
2023/11/22
1570
类和继承
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。比如猫是一个类,那么我的猫就是一个实例对象。
y191024
2022/09/20
4990
Swift的属性,方法,下标脚本以及继承
从这篇章节起,Swift编程语言指南大部分的重要内容在于概念,代码并非太多。理解Swift的面向对象理念,语法以及类结构,构造析构过程对于非常好的应用Swift语言将会有比較大的帮助。
全栈程序员站长
2022/07/14
9020
Swift的属性,方法,下标脚本以及继承
Java 继承与多态:代码重用与灵活性的巧妙结合
在 Java 中,可以从一个类继承属性和方法到另一个类。我们将“继承概念”分为两类:
小万哥
2024/02/29
2010
Java 继承与多态:代码重用与灵活性的巧妙结合
适合初学者学习的面向对象编程(OOP)入门指南
类是一种蓝图,用来创建对象。它定义了对象将拥有的属性和方法。就像建房子的图纸一样,图纸决定了房子的结构和功能,但并不是真正的房子。
前端达人
2024/06/27
3140
适合初学者学习的面向对象编程(OOP)入门指南
JavaScript设计模式总汇
来源 | http://www.fly63.com/article/detial/10063
前端达人
2021/01/27
5920
JavaScript设计模式总汇
Python基础——面相对象的三大特征【封装,继承,多态】
📝前言: 上一篇文章Python基础——类讲解了python语法中的类,类是面相对象的模版,这篇文章我们就初步讲解面相对象的三大特征: 1,封装 2,继承 3,多态
用户11029137
2024/04/15
2690
Python基础——面相对象的三大特征【封装,继承,多态】
万字长文|Swift语法全面解析|附示例
Swift 是一门开发 iOS, macOS, watchOS 和 tvOS 应用的新语言。 swift 是一种安全,快速和互动的编程语言。 swift 支持代码预览(playgrounds),这个特性可以允许程序员在不编译和运行应用程序的前提下运行 Swift 代码并实时查看结果。
悟空聊架构
2020/07/30
3.8K0
java 继承是什么_java中继承指的是什么
这篇文章将为大家详细讲解有关java中继承指的是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
全栈程序员站长
2022/07/18
6970
java 继承是什么_java中继承指的是什么
swift 构造器
使用构造器来实现构造过程,构造器可以看做是用来创建新实例的特殊方法,与OC的构造器不同,之前是先调用父类的init再写自己的, 但是到了Swift里面, 我们却先初始化自己, 再初始化父类, 是相反的,swift中构造器无需返回值,主要任务是保证新实例在第一次使用前完成正确的初始化
xy_ss
2023/11/22
2010
swift  构造器
Java 中文官方教程 2022 版(四)
你可以使用 lambda 表达式来创建匿名方法。然而,有时候 lambda 表达式仅仅是调用一个已存在的方法。在这种情况下,通过名称引用现有方法通常更清晰。方法引用使你能够做到这一点;它们是紧凑、易读的 lambda 表达式,用于已经有名称的方法。
ApacheCN_飞龙
2024/05/24
2050
混合对象“类”
JavaScript提供了更接近传统语言的写法,引入了class(类),作为对象的模板。通过class关键字,可以定义类。
Karl Du
2020/10/23
7580
混合对象“类”
混合设计“类”
类 / 继承描述了一种代码的组织结构形式 ,一种在软件中对真实世界中问题领域的建模方法。
Karl Du
2023/10/20
1930
混合设计“类”
Swift基础 属性
翻译自:https://docs.swift.org/swift-book/LanguageGuide/Properties.html
郭顺发
2023/07/17
2520
Swift基础 类型铸造
翻译自:https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html
郭顺发
2023/07/17
1070
相关推荐
Swift2.1-继承继承
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档