(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);
varBtn: TButton;
beginBtn := 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.mzph.cn/news/764609.shtml

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

相关文章

【Java前端技术栈】Vue2、Vue Cli、Axio入门

一、基本介绍 1.Vue 是什么? Vue (读音 /vjuː/,类似于 view) 是一个前端框架, 易于构建用户界面 2. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合 3. 支持和其它类库结合使用 4. 开发复杂的单页应用非常方便 5.…

动态规划——数字三角形模型

母题:数字三角形 集合:f[i][j]表示所有从起点走到 ( i , j ) (i,j) (i,j)的路径 属性:f[i][j]存的数是集合中所有路径和的最大值 状态计算:对于每一条从起点到 ( i , j ) (i,j) (i,j) 的路径,其要么是从左上方来的…

如何了解AI基础概念

1. **在线课程和教程:** - 寻找在线AI课程或教程,例如Coursera、edX、Udemy等平台上的课程。这些课程通常会从基础概念开始介绍,逐步深入。 2. **书籍阅读:** - 阅读与AI相关的书籍,如《Python深度学习》、《机…

[Rust] 使用vscode实现HelloWorld程序并进行debug

一、简介 本文介绍了如何使用vscode编写rust,实现打印"Hello, world!"的程序。 二、工具安装 0. 环境介绍: Linux (或者windowswsl) 1. 安装rust编译器rustc和包管理器cargo。 请参考连接:Rust 程序设…

vue集成百度地图,实现关键字搜索并自定义覆盖物,保存成静态图片

vue集成百度地图&#xff0c;实现关键字搜索并自定义覆盖物 index.html引入百度地图js <script type"text/javascript" src"https://api.map.baidu.com/api?v2.0&typewebgl&akxxxxxxwMprS7jIfPt354VdgP"></script>vue页面代码 <…

Android iOS客户端自动化UI自动化airtest从0到1搭建macos

一、基础环境 1. 安装jdk 选择jdk8 如果下载高版本 可能不匹配会失败 下载.dmg文件 苹果电脑 &#xff5c; macOS &#xff5c; jdk1.8 &#xff5c; 环境变量配置_jdk1.8 mac-CSDN博客 Java Downloads | Oracle jdk环境变量配置 找到java home qamac ~ % cd /Library/J…

K8s+Nacos实现应用的优雅上下线【生产实践】

文章目录 前言一、环境描述二、模拟请求报错三、配置优雅上下线1.修改nacos配置2.修改depolyment配置3.重新apply deployment后测试4.整体(下单)测试流程验证是否生效 四、期间遇到的问题 前言 我们在使用k8s部署应用的时候&#xff0c;虽然k8s是使用滚动升级的&#xff0c;先…

【AI生成文章】flutter ChangeNotifierProvider 实用场景举例

内容由Ai 大模型生成&#xff0c;不能完全保障真实 ChangeNotifierProvider 是 Flutter 中一个非常实用的工具&#xff0c;用于在应用程序中管理和传递状态。以下是一些实用的场景举例&#xff1a; 1. 用户信息管理 在应用程序中&#xff0c;用户信息&#xff08;如用户名、…

【Android】【Bluetooth Stack】蓝牙音乐协议分析之音频控制与信息加载(超详细)

1. 精讲蓝牙协议栈(Bluetooth Stack):SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅,【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待! 目录 1. 音乐信息加载 1.1 歌曲信息 1.1.1 key_c…

selenium自动化登录模块HTMLTestRunner测试报告

1.下载HTMLTestRunner.py放到python的Lib目录下&#xff0c;python3之后的&#xff0c;文件要修改以下内容&#xff1a; 第94行&#xff0c;将import StringIO修改成import io 第539行&#xff0c;将self.outputBuffer StringIO.StringIO()修改成self.outputBuffer io.Strin…

【微服务】微服务架构的最佳实践总结!

目录 推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战构建和管理微服务是一项艰巨的任务。这是因为微服务就像多个并行的整体应用程序,它们都必须处于同步通信和并发运行时间。因此,在设计和构建它们时考虑并应用最佳实践非常重要。以下…

C++ —— 日期计算器

1. 头文件 #pragma once #include <iostream> using namespace std;class Date { public:Date(int year 1, int month 1, int day 1);int GetMonthDay();bool operator>(const Date& d) const;bool operator>(const Date& d)const;bool operator<(c…

单例模式:双重效验锁的懒汉实现方式

单例模式&#xff1a;双重效验锁的懒汉实现方式 单例模式饿汉模式实现懒汉模式实现改进1 (创建多个实例)改进2 (性能比较低)改进3 (volatile禁止指令重排序) 单例模式 单例模式顾名思义就是指实例化一个对象&#xff0c;通过把构造方法私有化来禁止创建实例。 饿汉模式实现 饿汉…

GPU算力池管理工具Determined AI部署与使用教程(2024.03)

1. 概念 1.1 什么是Determined&#xff1f; Determined AI 是一个全功能的深度学习平台&#xff0c;兼容 PyTorch 和 TensorFlow。它主要负责以下几个方面&#xff1a; 分布式训练&#xff1a;Determined AI 可以将训练工作负载分布在多个 GPU&#xff08;可能在多台计算机上…

大模型开发中使用prompt提示最佳实践

在大型模型开发中&#xff0c;使用prompt&#xff08;提示&#xff09;是一种指导模型生成所需输出的方法。以下是在使用prompt时的一些最佳实践&#xff1a; 1、明确的提示&#xff1a;确保prompt提供了明确、清晰的指导&#xff0c;以便模型理解所需生成的内容。避免模棱两可…

IPP-7010 表面贴装 90 度混合耦合器

IPP-7010 表面贴装 90 度混合耦合器 IPP-7010 是一款表面贴装 90 度混合耦合器&#xff0c;工作频率为 800 至 2500 MHz&#xff08;0.8 至 2.5 GHz&#xff09;&#xff0c;平均额定功率为 200 瓦。IPP-7010 采用 0.40 x 1.80 英寸表面贴装封装。IPP-7010的幅度平衡小于0.6dB&…

鸿蒙预览报错 Only files in a module can be previewed

HarmonyOS第一课下载的源码无法运行&#xff0c;也无法预览&#xff0c;报错如题。 解决&#xff1a; 1、在预览页如“index.ets”文件下预览。 2、如果在通知栏看到如图提示&#xff0c;可看出是ohos/hvigor-ohos-plugin插件版本的问题&#xff0c;可点击蓝色解决方案同步并导…

HTTP Header Fields

HTTP&#xff08;超文本传输协议&#xff09;中包含多种类型的头部字段&#xff08;Header Fields&#xff09;&#xff0c;以下是常见的HTTP头部字段及其作用&#xff1a; ### 通用头字段&#xff08;General Header Fields&#xff09; - **Cache-Control**: 控制缓存行为&a…

python 函数(解包**、互相调用、作用域、函数的封装、内置函数:eval()、zip()、文件处理open())

函数解包 """ 1、函数的注释&#xff1a;参数和返回值 在注释里可以自动添加显示&#xff0c;只需手动加说明。2、函数的解包【拆包】&#xff1a;函数的参数要传递数据有多个值的时候&#xff0c;中间步骤拿到数据 保存在元组或者列表 或者字典里。 - 传递参数…

活用 C语言之union的精妙之用

一、union的基本定义 Union的中文叫法又被称为共用体、联合或者联合体。它的定义方式与结构体相同,但意义却与结构体完全不同。下面是union的定义格式: union 共用体名 {成员列表}共用体变量名;它与结构体的定义方式相同,但区别在于共用体中的成员的起始地址都是相同的,…