(delphi11最新学习资料) Object Pascal 学习笔记---第8章第6节(安全类型转换运算符)

8.6 安全类型转换运算符

​ 正如我们之前所见,子类的语言类型兼容性规则允许你在期望祖先类的地方使用子类。如我所提到的,反向则不可能。

​ 现在假设TDog类有一个Eat方法,而TAnimal类中不存在此方法。如果变量FMyAnimal引用了一个狗,你可能希望能够调用这个函数。但如果你尝试调用,而变量指向的是另一个类,结果就会出错。通过显式类型转换,我们可能会导致令人讨厌的运行时错误(或者更糟糕的是,出现微妙的内存覆盖问题),因为编译器无法确定对象的类型是否正确,以及我们调用的方法是否确实存在。

​ 为了解决这个问题,我们可以使用基于运行时类型信息的技术。从本质上讲,因为每个对象在运行时“知道”自己的类型和父类。我们可以使用is运算符或使用TObject类的一些方法询问此信息。is运算符的参数是一个对象和一个类类型,返回值是一个布尔值:

if FMyAnimal is TDog then
  ...

​ 只有当 FMyAnimal 对象当前引用的是 TDog 类对象或 TDog 的子类且与 TDog 兼容时,is 表达式才会返回 True。这意味着,如果测试存储在 TAnimal 变量中的 TDog 对象是否真的是 TDog 对象,测试将会成功。换句话说,如果可以安全地将对象 (FMyAnimal) 赋值给数据类型 (TDog) 的变量,则该表达式的值为 True。

注解: 实际上,is 运算符的实现是由 TObject 类的 InheritsFrom 方法提供的。因此,您可以将相同的表达式写为 FMyAnimal.InheritsFrom(TDog)。直接使用这个方法的原因是它还可以应用于类引用和不支持 is 运算符的其他特殊类型。

现在您确信动物是一只狗后,可以通过以下代码使用直接类型转换(通常是不安全的):
if FMyAnimal is TDog then
begin
	MyDog := TDog(FMyAnimal);
	Text := MyDog.Eat;
end;

​ 同样的操作也可以直接通过另一个相关的类型转换运算符 as 来完成。as 仅在请求的类与实际类兼容时才转换对象,否则将导致运行时异常。as 运算符的参数是一个对象和一个类类型,结果是一个“转换”为新的类类型的对象。我们可以编写以下片段:

MyDog := FMyAnimal as TDog;
Text := MyDog.Eat;

如果只想调用 Eat 函数,还可以使用更简洁的表示法:

(FMyAnimal as TDog).Eat;

​ 这个表达式的结果是一个 TDog 类数据类型的对象,因此您可以对其应用该类的任何方法。传统转换和使用 as 转换的区别在于,后者会检查对象的实际类型,并在类型与试图转换的类型不兼容时引发异常。引发的异常是 EInvalidCast(下一章将介绍异常)

警告:相比之下,在 C# 语言中,如果对象与类型不兼容,则 as 表达式将返回 nil,而直接类型转换将引发异常。因此,基本上这两个操作与 Object Pascal 相比是相反的。

​ 要避免这种异常,请使用 is 运算符,如果成功,则进行普通类型转换(实际上,没有理由连续使用 isas,进行两次类型检查,尽管通常会看到它们的组合使用):

if FMyAnimal is TDog then
  TDog(MyAnimal).Eat;

​ 在 Object Pascal 中,这两个类型转换运算符非常有用,因为您通常希望编写可用于相同类型或不同类型的多个组件的通用代码。例如,当将组件作为参数传递给事件响应方法时,使用通用数据类型(TObject)时,通常需要将其转换回原始组件类型:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Sender is TButton then
  ...
end;

这是一种常用技术,我将在后面的示例中使用它(事件将在第 10 章中介绍)。

​ 这两个类型转换运算符 isas 非常强大,您可能会被诱使将其视为标准的编程构造。尽管它们确实很强大,但您可能应该将它们的使用限制在特殊情况下。当您需要解决涉及多个类的复杂问题时,请首先尝试使用多态。只有在特殊情况下,多态无法应用时,才应尝试使用类型转换运算符来作为补充。

注意:使用类型转换操作符会对性能产生轻微的负面影响,因为它必须遍历类的层次结构,以查看类型转换是否正确。正如我们所看到的,虚拟方法调用只需要查找内存,速度要快得多。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

android11 SystemUI入門之KeyguardPatternView解析

view层级树为&#xff1a; 被包含在 keyguard_host_view.xml中 。 <?xml version"1.0" encoding"utf-8"?> <!-- This is the host view that generally contains two sub views: the widget viewand the security view. --> <com.andro…

麻了,别再为难软件测试员了

前言 有不少技术友在测试群里讨论&#xff0c;近期的面试越来越难了&#xff0c;要背的八股文越来越多了,考察得越来越细&#xff0c;越来越底层&#xff0c;明摆着就是想让我们徒手造航母嘛&#xff01;实在是太为难我们这些测试工程师了。 这不&#xff0c;为了帮大家节约时…

RAG知识分享

文章目录 1.为什么要做RAG1.1. 解决幻觉问题1.1.1 直接输入问题1.1.2. 问题 相关知识 2. 什么是RAG2.1. 基本概念2.2. 基本RAG方法2.2.1. 知识预处理2.2.2. 知识检索2.2.3. 答案生成 3. RAG 与 Long Context3.1. Long Context3.2. RAG 与Long Context3.3 RAG对比Long Context的…

(2024,超分辨率,膨胀卷积和低通滤波,SD)FouriScale:免训练高分辨率图像合成的频率视角

FouriScale: A Frequency Perspective on Training-Free High-Resolution Image Synthesis 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 相关工作 2.2 通过扩散模型进行…

【攻防世界】ics-05

php://filter 伪协议查看源码 preg_replace 函数漏洞 1.获取网页源代码。多点点界面&#xff0c;发现点云平台设备维护中心时&#xff0c;页面发生变化。 /?pageindex 输入什么显示什么&#xff0c;有回显。 用php://filter读取网页源代码 ?pagephp://filter/readconvert.…

PC版复古珠宝饰品网站模板 基于pbootcms的首饰类源码下载

PbootCMS复古珠宝饰品网站模板&#xff1a;PCWAP双端同步&#xff0c;数据即时共享&#xff0c;轻松打造专业饰品首饰平台 本模板基于PbootCMS内核开发&#xff0c;专为饰品首饰网站、复古珠宝饰品网站等企业量身定制。同时&#xff0c;其他行业同样适用&#xff0c;只需替换文…

【PostgreSQL】技术传承:使用Docker快速部署PostgreSQL数据库

前言 PostgreSQL的重要贡献者Simon Riggs因一起坠机事故不幸离世。Simon Riggs是英国著名的软件与服务领导者&#xff0c;也是PostgreSQL的主要开发者和贡献者。事故发生在英国当地时间3月26日13:41分&#xff0c;当时他驾驶的私人通用航空Cirrus SR22飞机在英国达克斯福德机场…

SpringBoot整合Netty整合WebSocket-带参认证

文章目录 一. VectorNettyApplication启动类配置二.WebSocketServerBoot初始化服务端Netty三. WebsocketServerChannelInitializer初始化服务端Netty读写处理器四.initParamHandler处理器-去参websocket识别五.MessageHandler核心业务处理类-采用工厂策略模式5.1 策略上下文 六…

Thinkphp5萤火商城B2C小程序源码

源码介绍 Thinkphp5萤火商城B2C小程序源码&#xff0c;是一款开源的电商系统&#xff0c;为中小企业提供最佳的新零售解决方案。采用稳定的MVC框架开发&#xff0c;执行效率、扩展性、稳定性值得信赖。 环境要求 Nginx/Apache/IIS PHP5.4 MySQL5.1 建议使用环境&#xff…

代码随想录第三十天 | 回溯问题P6 | ● 332● 51● 37● 总结

332.重新安排行程 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机场&#xff09;出发的先生&#xff0c;所以该行程必须从 JFK…

docker从入门到熟悉

一、什么是docker&#xff1f; Docker是一个用于开发&#xff0c;交付和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分开&#xff0c;从而可以快速交付软件。借助Docker&#xff0c;您可以以与管理应用程序相同的方式来管理基础架构。通过利用Docker的快速交付…

11-1(2)-CSS 背景+CSS 精灵图

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 一、CSS 背景1 背景颜色2 背景色半透明3 背景图片4 背景平铺5 背景图片位置6 …

LCD屏幕mmap显示

目录 前言 一.LCD显示 二.LCD颜色显示 2.1 直接显示 2.2 mmap映射显示 前言 mmap是一种内存映射文件的方法&#xff0c;它允许将文件或其它对象映射到进程的地址空间。 使用mmap映射函数进行映射显示&#xff0c;与屏幕普通直接显示相比有很大的优势 一.LCD显示基础 像素、分辨…

2. 如何让mybatis-plus的逻辑删除注解@TableLogic临时失效

文章目录 如何让mybatis-plus的逻辑删除注解TableLogic临时失效1. 场景复现1.1 controller代码1.2 service层代码1.3 entity代码 2. 问题分析3. 解决方案3.1 说明3.2 核心代码3.3 service方法对应修改为3.4 运行结果 如何让mybatis-plus的逻辑删除注解TableLogic临时失效 1. 场…

数学矩阵GCD和lCM(详解)

矩阵乘法 知阵乘法是《线性代数》中的基础内容&#xff0c;但在考察数学的算法题中也会出现。 本节我们学习基础的矩阵乘法规则。 每个矩阵会有一个行数和一个列数&#xff0c;只有当相乘的两个矩阵的左矩阵的列数等于右矩阵的行数 时&#xff0c;才能相乘&#xff0c;否则不允…

移动Web学习05-移动端适配Less预处理器

7、移动端适配 7.1、什么是适配&#xff1f; 简单理解就是、同一个网页&#xff0c;在不同屏幕分辨率的设备下、显示还是一样的&#xff0c;你可以理解为、网页当中的图片&#xff0c;盒子之间的距离、文字的大小、随着屏幕分辨率的变化而变化 前面我们学习了flex布局的方式…

关系型数据库与非关系型数据库、Redis数据库

相比于其他的内存/缓存数据库&#xff0c;redis可以方便的实现持久化的功能&#xff08;保存至磁盘中&#xff09; 一、关系数据库与非关系型数据库 1.1 关系型数据库 一个结构化的数据库&#xff0c;创建在关系模型基础上一般面向于记录 SQL语句 (标准数据查询语言) 就是一种…

二叉树学习

树 树是n个结点的有限集合&#xff0c;当n0时为空树&#xff0c;在任意一颗非空的树中&#xff0c;有且只有一个特定的称为根的结点&#xff0c;当n>1时&#xff0c;其余结点又可以分为m个不相交的有限集&#xff0c;其中每一个集合又是一棵树&#xff0c;并且称为根的子树…

深度学习方法;乳腺癌分类

乳腺癌的类型很多&#xff0c;但大多数常见的是浸润性导管癌、导管原位癌和浸润性小叶癌。浸润性导管癌(IDC)是最常见的乳腺癌类型。这些都是恶性肿瘤的亚型。大约80%的乳腺癌是浸润性导管癌(IDC)&#xff0c;它起源于乳腺的乳管。 浸润性是指癌症已经“侵袭”或扩散到周围的乳…

c# wpf template itemtemplate+dataGrid

1.概要 2.代码 <Window x:Class"WpfApp2.Window8"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend…