Swift构造器继承链

news2024/11/25 4:46:56

 类类型的构造器代理

Swift构造器需遵循以下三大规则:

  1. 指定构造器必须调用它直接父类的指定构造器方法
  2. 便利构造器必须调用同一个类中定义的其他初始化方法
  3. 便利构造器在最后必须调用一个指定构造器

两段式构造过程

Swift 中类的构造过程包含两个阶段。第一个阶段,类中的每个存储型属性赋一个初始值。当每个存储型属性的初始值被赋值后,第二阶段开始,它给每个类一次机会,在新实例准备使用之前进一步自定义它们的存储型属性。

两段式构造过程的使用让构造过程更安全,同时在整个类层级结构中给予了每个类完全的灵活性。两段式构造过程可以防止属性值在初始化之前被访问,也可以防止属性被另外一个构造器意外地赋予不同的值。

Swift提供了4种安全检查是开发者必须遵循的。

  1. 若子类中定义了父类没有的变量,则在子类的指定构造器中需先对该变量赋值,再调用父类的构造器。
  2. 若要在子类的指定构造器中修改继承来的变量的值,则需先调用父类的构造器。
  3. 若要在子类的便利构造器中修改任意变量的值,则需先调用同类的构造器。
  4. 所有属性被赋初始值后(即第一阶段结束后)才能调用实例方法。

阶段 1

类的某个指定构造器或便利构造器被调用。

完成类的新实例内存的分配,但此时内存还没有被初始化。

指定构造器确保其所在类引入的所有存储型属性都已赋初值。存储型属性所属的内存完成初始化。

指定构造器切换到父类的构造器,对其存储属性完成相同的任务。

这个过程沿着类的继承链一直往上执行,直到到达继承链的最顶部。

当到达了继承链最顶部,而且继承链的最后一个类已确保所有的存储型属性都已经赋值,这个实例的内存被认为已经完全初始化。此时阶段 1 完成。

阶段 2

从继承链顶部往下,继承链中每个类的指定构造器都有机会进一步自定义实例。构造器此时可以访问 self、修改它的属性并调用实例方法等等。

最终,继承链中任意的便利构造器有机会自定义实例和使用 self

构造器的继承和重写

规则:

  • 若定义的子类构造器与父类指定构造器相匹配,则需要在定义子类构造器时加上override 修饰符。
  • 若定义的子类构造器与父类便利构造器相匹配,不需要加override修饰符。
  • 若父类的指定构造器无参数,且在子类构造器中没有自定义父类的属性,那么在子类指定构造器中可以省略 super.init()
import UIKit

class lei{
    var name: String?
    init(){
        self.name = "123"
    }
}

class sublei: lei{
    var color: String
    init(color: String) {
        self.color = color
        //隐式调用super.init()
    }
}

构造器的自动继承

假设你为子类中引入的所有新属性都提供了默认值,以下 2 个规则将适用: 

规则 1: 如果子类没有定义任何指定构造器,它将自动继承父类所有的指定构造器。

import UIKit

class lei{
    var name: String?
    init(_ name: String){
        self.name = name
    }
}

class sublei: lei{
    var color = "123"
}

let a = sublei("abc")

规则 2: 如果子类提供了所有父类指定构造器的实现——无论是通过规则 1 继承过来的,还是提供了自定义实现——它将自动继承父类所有的便利构造器。 即使你在子类中添加了更多的便利构造器,这两条规则仍然适用。

注意: 子类可以将父类的指定构造器实现为便利构造器来满足规则 2。 

import UIKit

class lei{
    var name: String?
    init(_ name: String){
        self.name = name
    }
    convenience init(){
        self.init("abc")
    }
}

class sublei: lei{
    var color: String?
    init(_ name: String, _ color: String?){
        self.color = color
        super.init(name)
    }
    convenience override init(_ name: String) {
        self.init(name, nil)
    }
}


let one = sublei()

可失败构造器的重写与继承

语法:init?()

可失败构造器会创建一个类型为自身类型的可选类型的对象。你通过 return nil语句来表明可失败构造器在何种情况下应该 “失败”。

严格来说,构造器都不支持返回值。因为构造器本身的作用,只是为了确保对象能被正确构造。因此你只是用 return nil表明可失败构造器构造失败,而不要用关键字 return来表明构造成功。

重写可失败构造器可以在子类中定义一个非可失败构造器。

注意:

可以用非可失败构造器重写可失败构造器,但反过来却不行。

import UIKit

class lei{
    var name: String?
    init(){}
    
    init?(_ name: String){
        if name.isEmpty { return nil }
        self.name = name
    }
}

class sublei: lei{
    override init() {
        super.init()
        self.name = "abc"
    }
    override init(_ name: String) {
        super.init()
        if name.isEmpty{
            self.name = "abc"
        }else{
            self.name = name
        }
    }
}

你可以在子类的不可失败构造器中使用强制解包来调用父类的可失败构造器。比如,下面的 suble子类的 name 属性的值总是 "abc",它在构造过程中使用了父类的可失败构造器 init?(name:):

class sublei: lei {
override init() {
super.init(name: "abc")!
	}
}

 在这个例子中,如果在调用父类的可失败构造器 init?(name:) 时传入的是空字符串,那么强制解包操作会引发运行时错误。不过,因为这里是通过字符串常量来调用它,构造器不会失败,所以并不会发生运行时错误。

必要构造器

在类的构造器前添加 required修饰符表明所有该类的子类都必须实现该构造器:

class SomeClass {
    required init() {
        // 构造器的实现代码
    }
}

在子类重写父类的必要构造器时,必须在子类的构造器前也添加 required修饰符,表明该构造器要求也应用于继承链后面的子类。在重写父类中必要的指定构造器时,不需要添加 override修饰符:

class SomeSubclass: SomeClass {
    required init() {
        // 构造器的实现代码
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1265372.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

流程控制翻转学习

📑前言 本文主要是【Python】——Python流程控制翻转学习的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每…

STM32_10(I2C)

I2C通信 I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线两根通信线:SCL(Serial Clock)、SDA(Serial Data)同步,半双工带数据应答支持总线挂载多设备(一主多从…

Elasticsearch 线上实战问题及解决方案探讨

1、reindex相关问题 1.1 问题描述 我有 1tb 的一个大索引若干,要迁移到另外一个新集群去,有没有好办法?reindex好像会中断...... reindex 是不是就算设置了频率也会莫名的中断,而且没地方查到错误?1000多万的数据&…

盖茨表示GPT-5不会比GPT-4有太大改进;Intro to Large Language Models

🦉 AI新闻 🚀 盖茨表示GPT-5不会比GPT-4有太大改进 摘要:比尔盖茨在与德国《商报》的采访中透露,虽然OpenAI内部有人相信GPT-5会优于GPT-4,但他认为目前的生成式人工智能已经达到极限。盖茨对GPT-5未来的发展并不乐观…

视频集中存储/磁盘阵列EasyCVR平台黑名单异常解决步骤是什么?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…

七、Lua字符串

文章目录 一、字符串(一)单引号间的一串字符(二)local str "Hello, "(三)[[ 与 ]] 间的一串字符(四)例子 二、字符串长度计算(一)string.len&…

nginx 配置跨域(小皮面板)

本地开发的时候,前端请求后端,后端不能用域名请求,只能用端口模式,在小皮面板的话就是如下配置: 我的测试项目部署: 前端:http://localhost:8082 后端:http://localhost:8081 前端…

与珎同行录-开篇-231129

与珎同行录-开篇 珎就是对陪伴并帮助我写代码的AI的昵称 能不能读懂这个绕口令问题呢? 连续的椎体的相邻椎体质心的相邻质心的质心作为当前质心所在的椎体的质心, 该质心的方向代表该椎体的上下方向 如何代码实现呢? 还是没看懂…好吧最终的算法是:

vue建立组件无校验版

实现功能&#xff1a; 切换&#xff0c;相当于tab 1、非组件代码&#xff1a; <template><div><div class"tabStyle"><div v-for"(item,index) in tabTitle" :key"index" class"bordItemStyle" :class"c…

类指针压缩空间

一、类指针压缩介绍 压缩指针&#xff0c;指的是在 64 位的机器上&#xff0c;使用 32 位的指针来访问数据&#xff08;堆中的对象或 Metaspace 中的元数据&#xff09;的一种方式。 对象头中的 Class Pointer 默认占 8 个字节&#xff0c;开启 -XX:UseCompressedOops 后&…

git的创建以及使用

1、上传本地仓库 首先确定项目根目录中没有.git文件&#xff0c;有的话就删了&#xff0c;没有就下一步。在终端中输入git init命令。注意必须是根目录&#xff01; 将代码存到暂存区 将代码保存到本地仓库 2、创建git仓库 仓库名称和路径&#xff08;name&#xff09;随便写…

绝地求生:成长型皮肤异色定价是否有些夸张?

大家好&#xff0c;我闲游盒小盒子&#xff01; 自从26.2更新上架回归的黑市中四款成长型皮肤以后&#xff0c;能看到社区里很多玩家都分享抽中了自己心仪的成长型皮肤。 但是对于异色很少有人去实装&#xff0c;大多数玩家都是选择去分解异色换取五张图纸然后追求升级原皮等级…

leetcode:2549. 统计桌面上的不同数字(python3解法)

难度&#xff1a;简单 给你一个正整数 n &#xff0c;开始时&#xff0c;它放在桌面上。在 109 天内&#xff0c;每天都要执行下述步骤&#xff1a; 对于出现在桌面上的每个数字 x &#xff0c;找出符合 1 < i < n 且满足 x % i 1 的所有数字 i 。然后&#xff0c;将这些…

链接1:编译器驱动程序

文章目录 GNU编译器示例编译 GNU编译器 GNU编译器&#xff08;GNU Compiler&#xff09;是由自由软件基金会&#xff08;Free Software Foundation&#xff0c;FSF&#xff09;开发和维护的一套编译器集合。这些编译器主要用于编译各种编程语言的源代码&#xff0c;将其转换为…

汽车电子 -- 车载ADAS之FCW(前方碰撞预警)

相关法规文件: FCW: GB∕T 33577-2017 智能运输系统 车辆前向碰撞预警系统 性能要求和测试规程 一、前方碰撞预警 FCW&#xff08; Forward Collision Warning&#xff09; 参看&#xff1a;法规标准-GB/T 33577标准解读(2017版) 1、状态机 系统关闭 当车辆前向碰撞预警系…

08-学成在线项目中统一异常处理的规范

项目中的异常处理 规范异常类型 在Service类的业务方法中有很多的参数合法性校验,当请求参数不合法的时候会抛出异常,但此时异常信息只会在控制台输出,前端界面并不会提示用户 实际开发中前端和后端需要做一些约定: 一般将错误提示信息统一以json格式返回给前端,以HTTP状态码…

excel表格在线编辑(开源版)

文章目录 前言一、Luckysheetvue3vite 例子如有启发&#xff0c;可点赞收藏哟~ 前言 本文记录好用的开源在线表格 具体如图显示 另外记录下更名后的univer~&#xff0c;如下图&#xff08;有兴趣可自行详细了解&#xff09; univer 在线思维导图 一、Luckysheet 参考git…

【LeetCode】每日一题 2023_11_28 设计前中后队列(数组/链表/双端队列)

文章目录 刷题前唠嗑题目&#xff1a;设计前中后队列题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 这道题的难度&#xff0c;才是我想象中的中等题的难度好吧&#xff0c;昨天那玩意对我来说还是太难了…

WebUI自动化学习(Selenium+Python+Pytest框架)003

1.元素操作 在成功定位到元素之后&#xff0c;我们需要对元素进行一些操作动作。常用的元素操作动作有&#xff1a; &#xff08;1&#xff09;send_keys() 键盘动作&#xff1a;向浏览器发送一个内容&#xff0c;通常用于输入框输入内容或向浏览器发送快捷键 &#xff08;2…

C语言——有一个3*4的矩阵,要求求出其中值最大的那个元素的值,以及其所在的行号和列号

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int i,j,row0,colum0,a[3][4]{{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};int maxa[0][0];for ( i 0; i < 3; i)//行&#xff08;row&#xff09;{for ( j 0; j < 4; j)//列&#xff08;colum&#xf…