(delphi11最新学习资料) Object Pascal 学习笔记---第7章第4节(Self 标识符)

7.4 Self 标识符

​ 我们已经看到类的方法非常类似于过程和函数。真正的区别在于,方法有一个额外的隐式参数。这是对当前对象的引用,即应用方法的对象。在方法中,您可以使用Self标识符引用这个参数,即当前对象,如前面第5章“Self:记录背后的魔法”部分所述。

​ 当您创建同一类的多个对象时,这个额外的隐藏参数是必需的,以便每次将方法应用于其中一个对象时,该方法将仅操作该特定对象的数据,而不影响同一类的其他对象。

注解:Self标识符的概念和实现在记录和类之间非常相似。从历史上讲,Self首先用于类,后来在向记录添加方法时也扩展到了记录。

​ 例如,在先前列出的TDate类的SetValue方法中,我们简单地使用Month、Year和Day引用当前对象的字段,您可能会表示为:

Self.FMonth := M;
Self.FDay := D;

​ 实际上,这是Object Pascal编译器翻译代码的方式,而不是您应该编写代码的方式。Self标识符是编译器使用的基本语言构件,但有时程序员使用它来解决名称冲突并使代码更具可读性。

注解:C++、Java、C#和JavaScript语言都具有类似于this关键字的功能。但是,在JavaScript中,使用this在方法中引用对象字段是强制性的,这点不同于C++、C#和Java。

​ 关于Self,您真正需要知道的是调用方法的技术实现与调用通用子例程的实现有所不同。方法有一个额外的隐藏参数Self。由于所有这些都在幕后进行,您现在不需要知道Self是如何工作的。

​ 第二个重要的事情是您可以显式使用Self引用整个当前对象,例如将当前对象作为参数传递给另一个函数。

7.4.1 动态创建组件

​ 举个刚才提到的例子,当你需要在某个方法中明确引用当前窗体时,通常会用到 Self 标识符。

​ 一个典型的例子是在运行时创建一个组件,在这种情况下,你必须将组件的所有者传给它的 Create 构造函数,并将相同的值赋给它的 Parent 属性。在这两种情况下,你都必须提供当前窗体对象作为参数或值,而最好的方法就是使用 Self 标识符。

注解:组件的所有权表示两个对象之间的生命周期和内存管理关系。当组件的所有者被释放时,组件也将被释放。父子关系指的是可视化控件托管在其表面一个子控件。

为了演示这类代码,我编写了 CreateComps 示例。这个应用程序有一个没有组件的简单窗体,它有一个 OnMouseDown 事件的处理程序,该处理程序的参数还包括鼠标点击的位置。我需要这些信息来在该位置创建一个按钮组件。

注解:事件处理程序是第 10 章中涉及的一种特殊方法,与我们在本书中已经使用过的按钮 OnClick 事件处理程序同属一个系列。

这是该方法的代码:

procedure TForm1.FormMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Btn: TButton;
begin
  Btn := TButton.Create(Self);
  Btn.Parent := Self;
  Btn.Position.X := X;
  Btn.Position.Y := Y;
  Btn.Height := 35;
  Btn.Width := 135;
  Btn.Text := Format('At %d, %d', [X, Y]);
end;

请注意,您可能需要将StdCtrls单元添加到uses语句以编译此事件处理程序。

​ 如图 7.2 所示,这段代码的作用是在鼠标点击的位置创建按钮,并用标题标明具体位置(在本项目中,我禁用了 FMX 移动预览,以显示本地风格的 Windows 按钮,因为这样更清晰)。在上面的代码中,请特别注意 Self 标识符的使用,它既是 Create 方法的参数,也是 Parent 属性的值。

​ 在编写类似刚才代码的过程时,你可能会倾向于使用 Form1 变量而不是 Self。在这个具体的例子中,这种改变不会带来任何实际的差别(尽管这不是一个好的编码实践),但如果一个窗体有多个实例,使用 Form1 就真的是一个错误了。

​ 实际上,如果 Form1 变量指的是用该类型创建的窗体(一般是第一个窗体),并且如果创建了两个相同窗体类型的实例,通过点击任何后续窗体,新按钮将始终显示在第一个窗体中。它的所有者和父窗体将是Form1,而不是用户点击过的窗体。

​ 一般来说,在编写方法时,如果需要当前对象,就会引用同一类中的特定实例,这确实是一种糟糕的 OOP 编码风格。

图7.2: CreateComps示例在移动设备上的输出

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

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

相关文章

lora-scripts 训练IP形象

CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区,能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型(使用lora-scripts)-CSDN博客文章浏览阅读1.1k次…

Springboot+vue的高校实习管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频: Springbootvue的高校实习管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller&#xff09…

YOLOV8环境配置精简

AnacondaCUDA_cuDNN的安装这里就不详细介绍了,按照网上的教程基本可用,但是我的难题主要集中在Pycharm新建conda虚拟环境和Yolov8的工程验证上,所以本文记录自己解决问题的过程。 一,Ultralytics官网下载Yolov8源码,解…

stable diffusion 提示词进阶语法-年龄身材肤色-学习小结

stable diffusion 提示词进阶语法-年龄&身材&肤色 前言年龄提示词青年(18-25岁)幼年、少年(1-18)中年(35-60岁)老年(65-80岁 老爷爷 老奶奶) 身材提示词肤色关键词(人物基础…

Flink中JobManager与TaskManage的运行架构以及原理详解

Flink中JobManager与TaskManage的运行架构详解 整体架构 Flink的运行时架构中,最重要的就是两大组件:作业管理器(JobManger)和任务管理器(TaskManager)。对于一个提交执行的作业,JobManager是真…

Flume超级无敌详细讲解

简介 概述 Flume本身是由Cloudera公司开发的后来贡献给了Apache的一套针对日志进行收集(collecting)、汇聚(aggregating)和传输(moving)的分布式机制。 图-1 Flume图标 Flume本身提供了较为简易的流式结构,使得开发者能够较为简易和方便的搭建Flume的流动模型。 图-2 Flume…

【管理咨询宝藏56】大型德企业务战略规划报告

本报告首发于公号“管理咨询宝藏”,如需阅读完整版报告内容,请查阅公号“管理咨询宝藏”。 【管理咨询宝藏56】大型德企业务战略规划报告 【格式】PDF 【关键词】战略规划、商业分析、管理咨询 【核心观点】 - 这是一份非常完整的知名德企在华业务战略…

c++ 三元搜索 - 迭代与递归(Ternary Search)

计算机系统使用不同的方法来查找特定数据。有多种搜索算法,每种算法更适合特定情况。例如,二分搜索将信息分为两部分,而三元搜索则执行相同的操作,但分为三个相等的部分。值得注意的是,三元搜索仅对排序数据有效。在本…

数据分析案例-国际象棋顶级棋手数据可视化分析(文末送书)

🤵‍♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞&#x1f4…

Spring异步注解@Async线程池配置

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 从Spring3开始提供了@Async注解,该注解可以被标注在方法上,以便异步地调…

mysql字段多个值,mybatis/mybatis-plus匹配查询

mysql中有一个字段是字符串类型的,category字段值有多个用逗号分割的,例如:娱乐,时尚美妆,美食 。现在想实现这么一个功能, 前端传参 字符串,美食,娱乐。现在想在mybatis的xml中实现,查询,能查到…

Linux基础语法练习题,配有答案,题目内容如下:一、创建文件相关练习题二、文件管理相关练习题三、vim编辑器的练习四、用户管理相关操作

题目内容如下: 一、创建文件相关练习题 二、文件管理相关练习题 三、vim编辑器的练习 四、用户管理相关操作 一、创建文件相关练习题 1.进入根目录,列出当前目录的详细信息 2、在根目录下创建export目录 3.进入export目录,创建data目录 …

基于python+vue反诈科普平台的设计与实现flask-django-php-nodejs

课题主要采用Uni-weixin、django架构技术,前端以小程序页面呈现给用户,结合后台python语言使页面更加完善,后台使用MySQL数据库进行数据存储。微信小程序主要包括用户信息、反诈科普、一键举报、经历上传、交流论坛、科普测试、试题等功能&am…

嵌入式DSP教学实验箱操作教程:2-20 数模转换实验(模拟SPI总线输出电压值)

一、实验目的 掌握GPIO模拟SPI总线的使用,了解AD5724的芯片特性和使用,并实现基于AD5724输出电压值。 二、实验原理 StarterWare StarterWare是一个免费的软件开发包,它包含了示例应用程序。StarterWare提供了一套完整的GPIO寄存器配置接…

详细分析Python中的enumerate()函数(附多个Demo)

目录 前言1. 基本知识2. Demo 前言 对于Python的基本函数,从实战中获取确切知识 1. 基本知识 enumerate() 接受一个可迭代对象作为输入,并返回一个枚举对象这个枚举对象包含了原始可迭代对象中的每个元素以及对应的索引它允许在循环中同时获取索引和值…

linux系统------------MySQL 存储引擎

目录 一、存储引擎概念介绍 二、常用的存储引擎 2.1MyISAM 2.1.1MYlSAM的特点 2.1.2MyISAM 表支持 3 种不同的存储格式⭐: (1)静态(固定长度)表 (2)动态表 (3)压缩表 2.1.3MyISAM适…

Golang基础知识(笔记迁移)

golang 变量作用域 局部作用域:代码块、函数内的全局作用域:顶层作用域,代码块外的就是全局,如果变量名大写,则改变量整个程序都可以使用。 类型断言 golang的类型断言在变量后加上.(type),如果类型断言…

Java面试必问题16:HashMap和HashTable区别 ConcurrentHashMap和HashMap的区别

HashMap和HashTable区别 ConcurrentHashMap和HashMap是Java中常用的两种Map实现,它们之间有以下几个区别: 线程安全性:ConcurrentHashMap是线程安全的,多个线程可以同时对其进行读写操作而不需要额外的同步措施;而Has…

ARM32day4

VID_20240319_210515 1.思维导图 2.实现三个LED灯亮灭 .text .global _start _start: 使能GPIO外设时钟 LDR R0,0x50000A28 LDR R1,[R0]使能GPIOE ORR R1,R1,#(0X1<<4)使能GPIOF ORR R1,R1,#(0X1<<5) STR R1,[R0]设置引脚状态 LDR R0,0X50006000 LDR R1,[R0…

Linux-生产者与消费者模型

文章目录 一、什么是生产者与消费者模型&#xff1f;二、示例模型示例模型介绍交易场所&#xff08;blockQueue&#xff09;消费者与生产者运行结果 总结 一、什么是生产者与消费者模型&#xff1f; 参照日常生活中&#xff0c;购买商品的人群可以被称之为消费者&#xff0c;生…