草原云 發表於 2022-7-19 10:52:00

Delphi 小白来学类

<p><strong><span style="font-size: 16px">1.抽象&nbsp; (相当于制造前 画图纸/捏造/想象对象的阶段,还没开始造)</span></strong></p>
<p>1.1.类在 type 之下定义.</p>
<p>1.2.类的结构:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
    TPerson </span>= <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;类名为<span style="color: rgba(0, 0, 0, 1)">TPerson,你可以随便取,但应该符合命名规范.前面的T&nbsp;为类名约定前缀,你可以不要.</span></p>
&nbsp;
<p><span style="font-size: 16px"><strong><span style="color: rgba(0, 0, 0, 1)">2.实例化.(把抽象好的对象制造出来)所有的类都需要实例化才能使用.</span></strong></span></p>
<p><span style="color: rgba(0, 0, 0, 1)">2.1.如果你的类,抽象在A单元(窗体)中,想要在B单元(窗体)中使用,必须要先在B单元(窗口)的<span style="color: rgba(0, 0, 255, 1)">implementation</span>下面引用A单元才行,不然程序找不到你说的类</span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">implementation    //在这里引用, A 只能被本单元使用.即作用域为局部的.如果需要作为全局变量来使用,请把 A 放到顶部 interface 下的 Uses 下面</span>
<span style="color: rgba(0, 0, 255, 1)">uses</span> A;</pre>
</div>
<p>&nbsp;</p>
<p>2.2.我们添加了一个button,在它的事件里面使用这个类:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TForm1.Button1Click(Sender: TObject);
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
yadang: TPerson;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
yadang :</span>= TPerson.<span style="color: rgba(0, 0, 255, 1)">Create</span><span style="color: rgba(0, 0, 0, 1)">;  //<span style="color: rgba(0, 0, 255, 1)">Create</span> 制造实例<br>  //some code<br> yadang.free;    //有<span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)">Create </span></span>,就要有<span style="color: rgba(0, 0, 0, 1)">free</span> (销毁,释放内存).
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p><span style="font-size: 16px"><strong>3.销毁实例.</strong></span></p>
<p>上一段代码中,我们用TPerson这个类,制造出了一个真实存在的对象 yadang.然后yadang经历了他的一生,最后被 free 销毁掉了,尘世间只留下yadang的事迹,不再有yadang这个对象(释放内存).当然这里要留意一下,这里的yadang是个局部变量,在过程结束前free掉就可以了,但如果yadang是个全局变量,我们应该如何销毁呢?</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
Form1: TForm1;
<strong><span style="color: rgba(255, 0, 0, 1)"> yadang: TPerson;</span></strong>    //声明为全局变量

</span><span style="color: rgba(0, 0, 255, 1)">implementation</span>

<span style="color: rgba(0, 128, 0, 1)">{</span><span style="color: rgba(0, 128, 0, 1)">$R *.dfm</span><span style="color: rgba(0, 128, 0, 1)">}</span>
//在窗口被销毁前,销毁yadang
<span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TForm1.FormDestroy(Sender: TObject);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> yadang &lt;&gt; <span style="color: rgba(0, 0, 255, 1)">nil</span> <span style="color: rgba(0, 0, 255, 1)">then    //这里要做个判断,如果yadang没有被create,则销毁一个不存在的对象,程序会出错</span><span style="color: rgba(0, 0, 0, 1)">
    yadang.Free;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p><span style="font-size: 16px"><strong>4.类的数据成员.</strong></span></p>
<p>  4.1.给类添加属性.在上面1.2里,我们认识了类的结构,现在我们丰富它的属性,当然,这还是处于 '纸上谈兵' 的抽象阶段.</p>
<p>    数据成员多用于存放程序数据,方便各个窗体间调用,比如用户名,权限设置等等.</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
    TPerson </span>= <span style="color: rgba(0, 0, 255, 1)">class</span>
    <strong><span style="color: rgba(255, 0, 0, 1)">FName:string;</span></strong>    //你可以管它叫做(数据成员|变量|字段)都可以.开头的F为类成员约定前缀,你也可以不要<br>   <strong><span style="color: rgba(255, 0, 0, 1)"> FAge:integer;</span></strong>    
    <span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p> 4.2.设置与调用数据成员.</p>
<p>  4.2.1.设置类的数据成员.</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">//注意,这里的 <span style="color: rgba(0, 0, 0, 1)">yadang 是全局变量,所以free是在窗体的Destroy事件里执行.</span><br>procedure</span><span style="color: rgba(0, 0, 0, 1)"> TForm1.Button1Click(Sender: TObject);</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
yadang :</span>= TPerson.<span style="color: rgba(0, 0, 255, 1)">Create</span>;  <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Create 制造实例</span><br><span style="background-color: rgba(255, 255, 255, 1)"> <strong><span style="color: rgba(255, 0, 0, 1)">yadang .FName := '亚当';</span></strong></span>  //设置属性值<br> <strong><span style="color: rgba(255, 0, 0, 1)">yadang.FAge:= 20; </span></strong>
<span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;4.2.2.调用类的数据成员.如果没有预先设置数据成员的值,程序会抛出异常错误;</p>
<div class="cnblogs_code">
<pre><span style="font-size: 12px"><strong><span style="color: rgba(255, 0, 0, 1)">edit1.text:=yadang.FName;
edit2.text:=IntToStr(yadang.FAge);    </span></strong></span></pre>
</div>
<p>下面是整体的运行效果:</p>
<p>&nbsp;<img src="https://img2022.cnblogs.com/blog/981841/202207/981841-20220718092041976-878197347.png"></p>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong>5.类的属性.</strong></span>&nbsp;</p>
<p>  5.1抽象类的属性</p>
<div class="cnblogs_code">
<pre>TPerson = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    Fname: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;  //数据成员
    Fage: integer;  //数据成员
</span><span style="color: rgba(0, 0, 255, 1)">published</span>
   <span style="color: rgba(255, 0, 0, 1)"> property name: <strong><span style="color: rgba(0, 128, 128, 1)">string</span></strong> read Fname write Fname;  //属性,属性只是一个接口
    property age: <span style="color: rgba(0, 128, 128, 1)"><strong>integer</strong></span> read Fage write Fage;    //属性,属性只是一个接口
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>  上面的代码看起来是写了很多行,其实实际到写时,只要写两行标记为红色的代码,外加一个快捷方式就可以实现了</p>
<p>首先,输入" propf "选择第一个提示,就会得到一行属性 :<span style="color: rgba(255, 0, 0, 1)">property xxx : <strong><span style="color: rgba(0, 128, 128, 1)">type </span></strong>read Fxxx write Fxxx ;  <span style="color: rgba(0, 0, 0, 1)">xxx表示属性名称,这个你可以改成你想要的名字.后面的 <span style="color: rgba(255, 0, 0, 1)">read Fxxx write Fxxx 也要跟着改过来</span></span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">然后,改 <span style="color: rgba(255, 0, 0, 1)"><strong><span style="color: rgba(0, 128, 128, 1)">type</span></strong></span> 为你需要的数据类型,即 <span style="color: rgba(255, 0, 0, 1)"> xxx</span> 的数据类型.</span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">最后,用快捷方式: ctrl+shift+c快速完成其它部分</span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">  5.2属性的调用:</span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">    这就有点意思了.类的属性在访问里,用的是接口的名字<span style="color: rgba(255, 0, 0, 1)">name</span>和<span style="color: rgba(255, 0, 0, 1)">age</span> 属性,而不是<span style="color: rgba(255, 0, 0, 1)">Fname 和 <span style="color: rgba(255, 0, 0, 1)">Fage.<span style="color: rgba(0, 0, 0, 1)">因为这两个属性是私有的,外部不能直接访问,只能够通过接口来读写数据 ,这和直接访问数据成员的方式 略有不同.</span></span></span></span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><img src="https://img2022.cnblogs.com/blog/981841/202207/981841-20220718101731536-532741083.png"></span></span></span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>  5.3类的成员的访问权限&nbsp; 初识Private和Public关键字</p>
<p>  在上一节,我们在按下<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> ctrl+shift+c&nbsp;时,IDE会自动给我们添加了<span style="color: rgba(0, 0, 255, 1)">private</span>和<span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">published</span></span>.字面意思&nbsp;:</span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)">private</span></span></span>就是私有的,只允许本单元访问.</span></span></p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">published</span></span></span></span></span><span style="color: rgba(0, 0, 0, 1)">允许所有窗口访问.这里多说一句<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">published</span></span></span></span>&nbsp;与&nbsp;<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">public&nbsp;&nbsp;<span style="color: rgba(0, 0, 0, 1)">大体上可以通用,但<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">published <span style="color: rgba(0, 0, 0, 1)">多用于组件开发.一般情况下,我们用</span> public <span style="color: rgba(0, 0, 0, 1)">就可以了,更多详细请点这里</span><br></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">published&nbsp;与&nbsp;<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">public</span></span></span></span></span></span></span></span></span></span> 是可以同时存在类里面的,在Dev的TcxRTTIInspector &nbsp;(RTTI属性编辑器)里面,RTTI 只能获取到<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)">published&nbsp;</span></span></span></span></span></span>发布的内容,<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">public </span></span></span></span></span></span></span></span></span></span>里面的东西,它是获取不到的.</pre>
</div>
<p>&nbsp;</p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> </span></span></p>
<div class="cnblogs_code">
<pre>TPerson = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private    //私有的,只允许本单元访问</span><span style="color: rgba(0, 0, 0, 1)">
    Fname: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public    //改为 <span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">public,公共的,允许所有窗口访问</span></span></span><span style="color: rgba(255, 0, 0, 1)">
    Fage: integer;        //注意这一行,此时所有窗口都能直接访问这个Fage成员</span>
    <span style="color: rgba(0, 0, 255, 1)">property</span> name: <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(0, 0, 255, 1)">read</span> Fname <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fname;
    </span><span style="color: rgba(0, 0, 255, 1)">property</span> age: integer <span style="color: rgba(0, 0, 255, 1)">read</span> Fage <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fage;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> 在上面4.1节里,我们给出过一段代码,这里并没有直接设置<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)">private和<span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">public</span></span></span></span></span> 此时,程序会默认为<span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 0, 1)"> <span style="color: rgba(0, 0, 255, 1)">public</span></span></span></span></span></span></span> ,此时所有窗口都能直接访问这个类下的数据成员.<br></span></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
    TPerson </span>= <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">
    FName:</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;  //没有设置字段作用域,默认为public,所有窗口都可以访问  
    FAge:integer;    
    </span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: 16px; color: rgba(0, 0, 0, 1)">&nbsp;6.类的方法 (成员函数或者过程)-- 定义一个过程</span></strong></p>
<p><strong><span style="font-size: 16px; color: rgba(0, 0, 0, 1)">  6.1 </span>在public下定义一个<strong><span style="color: rgba(255, 0, 0, 1)">SayHellow</span></strong>过程 :<br></strong></p>
<p><strong>  &nbsp;</strong></p>
<div class="cnblogs_code">
<pre>TPerson = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    Fname: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
    Fage: integer;
</span><span style="color: rgba(0, 0, 255, 1)">public</span>
    <span style="color: rgba(0, 0, 255, 1)">property</span> name: <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(0, 0, 255, 1)">read</span> Fname <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fname;
    </span><span style="color: rgba(0, 0, 255, 1)">property</span> age: integer <span style="color: rgba(0, 0, 255, 1)">read</span> Fage <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fage;
    </span><strong><span style="color: rgba(255, 0, 0, 1)">procedure SayHellow(msg: string);    //过程
</span></strong><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p><strong>  然后按下快捷键 <span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> ctrl+shift+c,自动在下面生成过程框架</span></span><br></strong></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span> TPerson.SayHellow(msg: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>

<span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p>写上业务代码后,运行情况如下:</p>
<p>这里要啰嗦一句,调用类的方法时,仍然要判断一下这个类是否存在:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TForm1.Button4Click(Sender: TObject);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> yadang &lt;&gt;<span style="color: rgba(0, 0, 255, 1)">nil</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
   yadang .SayHellow(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Hellow!</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p><strong><span style="font-size: 16px; color: rgba(0, 0, 0, 1)"><img src="https://img2022.cnblogs.com/blog/981841/202207/981841-20220718104912465-1539896342.png"></span></strong></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>在上面的SayHellow过程里面,引用了私用成员Fname,因为是在本单元内使用,所以一点问题也没有.<strong><span style="color: rgba(255, 0, 0, 1)">这个Fname你还可以把它替换成其他过程或者函数,靠你自由发挥吧</span></strong></p>
<p>接口的作用就是把内部数据整理出来,然后通过接口发布出去,避免外部直接操作内部数据.</p>
<p><strong><span style="font-size: 16px; color: rgba(0, 0, 0, 1)">&nbsp;  6.2 创建一个自定义函数</span></strong></p>
<p><strong><span style="font-size: 16px; color: rgba(0, 0, 0, 1)">  </span></strong></p>
<div class="cnblogs_code">
<pre>TPerson = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    Fname: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
    Fage: integer;
    Fbrithday: TDate;
</span><span style="color: rgba(0, 0, 255, 1)">public</span>
    <span style="color: rgba(0, 0, 255, 1)">property</span> name: <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(0, 0, 255, 1)">read</span> Fname <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fname;
    </span><span style="color: rgba(0, 0, 255, 1)">property</span> age: integer <span style="color: rgba(0, 0, 255, 1)">read</span> Fage <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fage;
    </span><span style="color: rgba(0, 0, 255, 1)">property</span> brithday: TDate <span style="color: rgba(0, 0, 255, 1)">read</span> Fbrithday <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fbrithday;
    </span><span style="color: rgba(0, 0, 255, 1)">procedure</span> SayHellow(msg: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><strong><span style="color: rgba(255, 0, 0, 1)">function IsAdult: Boolean;      //定义一个函数
</span></strong><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p>按下<strong> <span style="color: rgba(255, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"> ctrl+shift+c,自动在下面生成函数框架,与过程的操作大同小异</span></span></strong></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> TPerson.IsAdult: Boolean;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> Now &gt;= IncYear(Fbrithday,<span style="color: rgba(128, 0, 128, 1)">18</span>) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    IsAdult :</span>=<span style="color: rgba(0, 0, 0, 1)"> True
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    IsAdult :</span>=<span style="color: rgba(0, 0, 0, 1)"> False;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p>调用:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TForm1.scDateEdit1Change(Sender: TObject);   
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> yadang &lt;&gt; <span style="color: rgba(0, 0, 255, 1)">nil</span> <span style="color: rgba(0, 0, 255, 1)">then</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
yadang.brithday :</span>=<span style="color: rgba(0, 0, 0, 1)"> scDateEdit1.Date;  //设置生日为当前控件的日期
</span><span style="color: rgba(0, 0, 255, 1)">if</span> yadang.IsAdult <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    Label3.Caption :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">我已成年</span><span style="color: rgba(128, 0, 0, 1)">'</span>
<span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    Label3.Caption :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">我未成年</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<pre><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">DateEdit 这里有个坑,手动输入的日期有时候是不会触发此事件的,原因是什么我也不知道 。所以最好的办法就是不要用change事件,应该设置一个button来执行这段代码。<br><br><strong><span style="font-size: 16px; color: rgba(0, 0, 0, 1)">&nbsp;7.类的构造函数 </span></strong></span></span></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;  7.1 构造关键字&nbsp;: constructor .说白了就是让我们抽象好的类,在成创建时,初始化一些参数。</p>
<p>    </p>
<div class="cnblogs_code">
<pre>TPerson = <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    Fname: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
    Fage: integer;
    Fbrithday: TDate;
</span><span style="color: rgba(0, 0, 255, 1)">public</span>
    <span style="color: rgba(0, 0, 255, 1)">property</span> name: <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(0, 0, 255, 1)">read</span> Fname <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fname;
    </span><span style="color: rgba(0, 0, 255, 1)">property</span> age: integer <span style="color: rgba(0, 0, 255, 1)">read</span> Fage <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fage;
    </span><span style="color: rgba(0, 0, 255, 1)">property</span> brithday: TDate <span style="color: rgba(0, 0, 255, 1)">read</span> Fbrithday <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> Fbrithday;
    </span><span style="color: rgba(0, 0, 255, 1)">procedure</span> SayHellow(msg: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> IsAdult: Boolean;
    </span><span style="color: rgba(255, 0, 0, 1)"><strong>constructor Create(AOwner: TComponent);
    constructor A(AOwner: TComponent);
    constructor B(AOwner: TComponent);
    constructor C(iFname:string);
    constructor D();</strong></span>
<span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>  对,你没有看错!!!<span style="color: rgba(255, 0, 0, 1)"><strong>constructor&nbsp;&nbsp; </strong></span><span style="color: rgba(0, 0, 0, 1)">是可以有N多个的!而且名字也不一定要是<span style="color: rgba(255, 0, 0, 1)"><strong>Create</strong></span> !但我劝你还是按规范来写,你可以写成<span style="color: rgba(255, 0, 0, 1)"><strong>Create</strong></span>A ,<span style="color: rgba(255, 0, 0, 1)"><strong>Create</strong></span>B ,但请不要像上面一样来个ABCD,让人看得想砸电脑。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">constructor</span> TPerson.<span style="color: rgba(0, 0, 255, 1)">Create</span><span style="color: rgba(0, 0, 0, 1)">(AOwner: TComponent);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Fname :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">张飞</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
Fage :</span>= <span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)">;
Fbrithday :</span>= StrToDate(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">1999-05-07</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>但是相应的,在创建类实例时,你就不能再写XXX.Create了!要写你对应的<span style="color: rgba(255, 0, 0, 1)"><strong> constructor A</strong></span> 中A的名字,比如 TXXXX.A,这点很重要.</p>
<p>通过初始化后,当这个TPerson类被创建之后,它的三个字段都有了初始值了,在很大程度上也避免了因为值为nil而产生的错误。</p>
<p>这里要吐槽一下Delphi的日期类型。我想写一个日期常量的,结果发现,我这点水平,真的写不出来。。。后来还是问了猫哥才知道,需要把字符串格式的日期转换一下,最简单的方案 StrToDate(<span style="color: rgba(128, 0, 0, 1)">'<span style="color: rgba(128, 0, 0, 1)">1999-05-07<span style="color: rgba(128, 0, 0, 1)">'<span style="color: rgba(0, 0, 0, 1)">)</span></span></span></span>。如果需要把日期转成文本,可以用DateToStr( yadang.brithday)</p>
<p>怎么调用我就不说了,跟函数一样用就行。</p>
<p>再来看下面这两个类,注意class后面参数与create后面参数的不同用法.</p>
<div class="cnblogs_code">
<pre>TTest=<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">
    constructor Create();
end;

TTest</span>=<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)">(TComponent)</span>
    constructor Create<span style="color: rgba(255, 0, 0, 1)">(AOwner: TComponent</span>);</span><strong><span style="color: rgba(255, 0, 0, 1)">override</span></strong><span style="color: rgba(0, 0, 0, 1)">;
end;</span></pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1>delphi的override、overload和virtual方法</h1>
<p><span style="font-size: 16px"><strong>8. 类的继承、派生 -- 认识TObject类</strong></span></p>
<p><span style="font-size: 16px"><strong>  这一节太理论了,我不知道怎么总结。我们打了个比方,上面第一节里说的类的定义,它就像是在乞丐家的儿子出生.....</strong></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
    TPerson </span>= <span style="color: rgba(0, 0, 255, 1)">class</span>

    <span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>下面这段就像是马斯克的儿子出生。。。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
    TPerson </span>= <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">(Tobject)

    </span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>大家明白意思了吧?父亲那里有什么东西可以用的,儿子就有什么东西可以用,这就是继承(不是我们遗产继承的那种继承)。</p>
<p>  然后呢,儿子们从父亲那里拿到了所有的东西,就开始作妖,自己又定义了一些自己的方法和属性,比如它用父亲的钱,做了一件花裤衩,这花裤衩是父亲们所没有的。这就叫派生。。。</p>
<p>最后大家来看一个人生赢家(它有五个爸爸):</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
    TPerson </span>= <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">(Tobject,A,B,C,D)

    </span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 16px"><strong>9.深入了解类的属性:读取和写入</strong></span></p>
<p> <strong><span style="font-size: 14px">9.1.属性具有三个要素:</span></strong></p>
<p>  1.数据类型(type)</p>
<p>  2.如何读取(Get)</p>
<p>  3.如何写入(Set)</p>
<p>  其中数据类型是每个属性都必须的,读和写按业务来选择.</p>
<p>  我们来看下面的几个属性设置:  </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">property</span> name: <span style="color: rgba(0, 0, 255, 1)">string</span> <span style="color: rgba(0, 0, 255, 1)">read</span> Fname <span style="color: rgba(0, 0, 255, 1)">write</span><span style="color: rgba(0, 0, 0, 1)"> SetFname;    //数据类型:string, 读取数据时直接读Fname的值,<span style="color: rgba(255, 0, 0, 1)">在赋值时执行SetFname过程
</span></span><span style="color: rgba(0, 0, 255, 1)">property</span> age: integer <span style="color: rgba(0, 0, 255, 1)">read</span><span style="color: rgba(0, 0, 0, 1)"> GetFage ;      <span style="color: rgba(0, 0, 0, 1)">//数据类型:integer ,<span style="color: rgba(255, 0, 0, 1)"> 读取数据时会执行GetFage函数</span>,不能给age属性赋值,只读</span>
</span><span style="color: rgba(0, 0, 255, 1)">property</span> brithday: TDate <span style="color: rgba(0, 0, 255, 1)">read</span> Fbrithday <span style="color: rgba(0, 0, 255, 1)">write</span> Fbrithday;  <span style="color: rgba(0, 0, 0, 1)">//数据类型:TDate , 读取数据时直接读Fbrithday 的值,赋值时,直接赋给Fbrithday ; 可读写</span></pre>
</div>
<p>按下ctrl+shift+c,在private下面会自动添加这两行代码</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span> setFname(<span style="color: rgba(0, 0, 255, 1)">const</span> Value: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">function</span> getFage: integer;</pre>
</div>
<p>同时也会在业务代码区,生成对应的过程或者函数框架.我们可以看到,set方法生成的是过程来给属性赋值,get方法生成的是函数,因为需要返回值 .</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> TPerson.getFage: integer;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>

<span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">procedure</span> TPerson.setFname(<span style="color: rgba(0, 0, 255, 1)">const</span> Value: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">begin<br>  if value.trim.isempty then exit;    //这里写一些你的业务代码<br></span><span style="color: rgba(0, 0, 0, 1)">
Fname :</span>=<span style="color: rgba(0, 0, 0, 1)"> Value;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;调用方式与上面讲的一样用就可以了.大家不要被这get和set迷惑,只要前期设置好业务逻辑就可以了.这两个家伙都是后台自动执行的,跟调用无关.</p>
<p>&nbsp;<span style="font-size: 16px"><strong>10. 内部类.类里面是可以再套类的</strong></span></p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">type</span><span style="color: rgba(0, 0, 0, 1)">
TOne </span>= <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    FSomeData: Integer;
</span><span style="color: rgba(0, 0, 255, 1)">public</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Nested constant</span>
    <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)">
      Foo </span>= <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Nested type</span>
    <span style="color: rgba(255, 0, 0, 1)">type
      TInside = class
      public
      procedure InsideHello;
      private
      FMsg: string;
      end;
</span><span style="color: rgba(0, 0, 255, 1)">public</span>
    <span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> Hello;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TOne.Hello;
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
Ins: TInside;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Ins :</span>= TInside.<span style="color: rgba(0, 0, 255, 1)">Create</span><span style="color: rgba(0, 0, 0, 1)">;
Ins.Msg :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Hi</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
Ins.InsideHello;
Show(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Constant is </span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> IntToStr(Foo));
Ins.Free;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TOne.TInside.InsideHello;    //注意这里名称的写法
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
FMsg :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">New msg</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
Show(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Internal call</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> Assigned(InsIns) <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    InsIns :</span>= TInsideInside.<span style="color: rgba(0, 0, 255, 1)">Create</span><span style="color: rgba(0, 0, 0, 1)">;
InsIns.Two;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TOne.TInside.TInsideInside.Two;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Show(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">This is a method of a nested/nested class</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 0, 1)">最后,转载一个很详细的案例,看你能否读懂:  </span></span></span></span></span></p>
<pre><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 0, 1)">Delphi: 圆形进度(环形进度)<br><img src="https://img2022.cnblogs.com/blog/981841/202210/981841-20221004092817750-161575476.png"></span></span></span></span></span></pre>
<p>&nbsp;</p>
<pre></pre>
<p>&nbsp;</p>
<pre><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 0, 1)"><br><br></span></span></span></span></span></pre><br><br>
来源:https://www.cnblogs.com/yoooos/p/16480718.html
頁: [1]
查看完整版本: Delphi 小白来学类