Delphi 小白来学类
作者:互联网
1.抽象 (相当于制造前 画图纸/捏造/想象对象的阶段,还没开始造)
1.1.类在 type 之下定义.
1.2.类的结构:
type TPerson = class end;
类名为TPerson,你可以随便取,但应该符合命名规范.前面的T 为类名约定前缀,你可以不要.
2.实例化.(把抽象好的对象制造出来)所有的类都需要实例化才能使用.
2.1.如果你的类,抽象在A单元(窗体)中,想要在B单元(窗体)中使用,必须要先在B单元(窗口)的implementation下面引用A单元才行,不然程序找不到你说的类
implementation //在这里引用, A 只能被本单元使用.即作用域为局部的.如果需要作为全局变量来使用,请把 A 放到顶部 interface 下的 Uses 下面 uses A;
2.2.我们添加了一个button,在它的事件里面使用这个类:
procedure TForm1.Button1Click(Sender: TObject); var yadang: TPerson; begin yadang := TPerson.Create; //Create 制造实例
//some code
yadang.free; //有Create ,就要有free (销毁,释放内存). end;
3.销毁实例.
上一段代码中,我们用TPerson这个类,制造出了一个真实存在的对象 yadang.然后yadang经历了他的一生,最后被 free 销毁掉了,尘世间只留下yadang的事迹,不再有yadang这个对象(释放内存).当然这里要留意一下,这里的yadang是个局部变量,在过程结束前free掉就可以了,但如果yadang是个全局变量,我们应该如何销毁呢?
var Form1: TForm1; yadang: TPerson; //声明为全局变量 implementation {$R *.dfm} //在窗口被销毁前,销毁yadang procedure TForm1.FormDestroy(Sender: TObject); begin if yadang <> nil then //这里要做个判断,如果yadang没有被create,则销毁一个不存在的对象,程序会出错 yadang.Free; end;
4.类的数据成员.
4.1.给类添加属性.在上面1.2里,我们认识了类的结构,现在我们丰富它的属性,当然,这还是处于 '纸上谈兵' 的抽象阶段.
数据成员多用于存放程序数据,方便各个窗体间调用,比如用户名,权限设置等等.
type TPerson = class FName:string; //你可以管它叫做(数据成员|变量|字段)都可以.开头的F为类成员约定前缀,你也可以不要
FAge:integer; end;
4.2.设置与调用数据成员.
4.2.1.设置类的数据成员.
//注意,这里的 yadang 是全局变量,所以free是在窗体的Destroy事件里执行.
procedure TForm1.Button1Click(Sender: TObject);begin yadang := TPerson.Create; //Create 制造实例
yadang .FName := '亚当'; //设置属性值
yadang.FAge:= 20; end;
4.2.2.调用类的数据成员.如果没有预先设置数据成员的值,程序会抛出异常错误;
edit1.text:=yadang.FName; edit2.text:=IntToStr(yadang.FAge);
下面是整体的运行效果:
5.类的属性.
5.1抽象类的属性
TPerson = class private Fname: string; //数据成员 Fage: integer; //数据成员 published property name: string read Fname write Fname; //属性,属性只是一个接口 property age: integer read Fage write Fage; //属性,属性只是一个接口 end;
上面的代码看起来是写了很多行,其实实际到写时,只要写两行标记为红色的代码,外加一个快捷方式就可以实现了
首先,输入" propf "选择第一个提示,就会得到一行属性 :property xxx : type read Fxxx write Fxxx ; xxx表示属性名称,这个你可以改成你想要的名字.后面的 read Fxxx write Fxxx 也要跟着改过来
然后,改 type 为你需要的数据类型,即 xxx 的数据类型.
最后,用快捷方式: ctrl+shift+c快速完成其它部分
5.2属性的调用:
这就有点意思了.类的属性在访问里,用的是接口的名字name和age 属性,而不是Fname 和 Fage.因为这两个属性是私有的,外部不能直接访问,只能够通过接口来读写数据 ,这和直接访问数据成员的方式 略有不同.
5.3类的成员的访问权限 初识Private和Public关键字
在上一节,我们在按下 ctrl+shift+c 时,IDE会自动给我们添加了private和 published.字面意思 :
private就是私有的,只允许本单元访问.
published允许所有窗口访问.这里多说一句 published 与 public 大体上可以通用,但 published 多用于组件开发.一般情况下,我们用 public 就可以了,更多详细请点这里
published 与 public 是可以同时存在类里面的,在Dev的TcxRTTIInspector (RTTI属性编辑器)里面,RTTI 只能获取到published 发布的内容, public 里面的东西,它是获取不到的.
TPerson = class private //私有的,只允许本单元访问 Fname: string; public //改为 public,公共的,允许所有窗口访问 Fage: integer; //注意这一行,此时所有窗口都能直接访问这个Fage成员 property name: string read Fname write Fname; property age: integer read Fage write Fage; end;
在上面4.1节里,我们给出过一段代码,这里并没有直接设置private和 public 此时,程序会默认为 public ,此时所有窗口都能直接访问这个类下的数据成员.
type TPerson = class FName:string; //没有设置字段作用域,默认为public,所有窗口都可以访问 FAge:integer; end;
6.类的方法 (成员函数或者过程)-- 定义一个过程
6.1 在public下定义一个SayHellow过程 :
TPerson = class private Fname: string; Fage: integer; public property name: string read Fname write Fname; property age: integer read Fage write Fage; procedure SayHellow(msg: string); //过程 end;
然后按下快捷键 ctrl+shift+c,自动在下面生成过程框架
procedure TPerson.SayHellow(msg: string); begin end;
写上业务代码后,运行情况如下:
这里要啰嗦一句,调用类的方法时,仍然要判断一下这个类是否存在:
procedure TForm1.Button4Click(Sender: TObject); begin if yadang <>nil then yadang .SayHellow('Hellow!'); end;
在上面的SayHellow过程里面,引用了私用成员Fname,因为是在本单元内使用,所以一点问题也没有.这个Fname你还可以把它替换成其他过程或者函数,靠你自由发挥吧
接口的作用就是把内部数据整理出来,然后通过接口发布出去,避免外部直接操作内部数据.
6.2 创建一个自定义函数
TPerson = class private Fname: string; Fage: integer; Fbrithday: TDate; public property name: string read Fname write Fname; property age: integer read Fage write Fage; property brithday: TDate read Fbrithday write Fbrithday; procedure SayHellow(msg: string); function IsAdult: Boolean; //定义一个函数 end;
按下 ctrl+shift+c,自动在下面生成函数框架,与过程的操作大同小异
function TPerson.IsAdult: Boolean; begin if Now >= IncYear(Fbrithday,18) then IsAdult := True else IsAdult := False; end;
调用:
procedure TForm1.scDateEdit1Change(Sender: TObject); begin if yadang <> nil then begin yadang.brithday := scDateEdit1.Date; //设置生日为当前控件的日期 if yadang.IsAdult then Label3.Caption := '我已成年' else Label3.Caption := '我未成年'; end; end;
DateEdit 这里有个坑,手动输入的日期有时候是不会触发此事件的,原因是什么我也不知道 。所以最好的办法就是不要用change事件,应该设置一个button来执行这段代码。
7.类的构造函数
7.1 构造关键字 : constructor .说白了就是让我们抽象好的类,在成创建时,初始化一些参数。
TPerson = class private Fname: string; Fage: integer; Fbrithday: TDate; public property name: string read Fname write Fname; property age: integer read Fage write Fage; property brithday: TDate read Fbrithday write Fbrithday; procedure SayHellow(msg: string); function IsAdult: Boolean; constructor Create(AOwner: TComponent); constructor A(AOwner: TComponent); constructor B(AOwner: TComponent); constructor C(iFname:string); constructor D(); end;
对,你没有看错!!!constructor 是可以有N多个的!而且名字也不一定要是Create !但我劝你还是按规范来写,你可以写成CreateA ,CreateB ,但请不要像上面一样来个ABCD,让人看得想砸电脑。
constructor TPerson.Create(AOwner: TComponent); begin Fname := '张飞'; Fage := 20; Fbrithday := StrToDate('1999-05-07'); end;
通过初始化后,当这个TPerson类被创建之后,它的三个字段都有了初始值了,在很大程度上也避免了因为值为nil而产生的错误。
这里要吐槽一下Delphi的日期类型。我想写一个日期常量的,结果发现,我这点水平,真的写不出来。。。后来还是问了猫哥才知道,需要把字符串格式的日期转换一下,最简单的方案 StrToDate('1999-05-07')。如果需要把日期转成文本,可以用DateToStr( yadang.brithday)
怎么调用我就不说了,跟函数一样用就行。
8. 类的继承、派生 -- 认识TObject类
这一节太理论了,我不知道怎么总结。我们打了个比方,上面第一节里说的类的定义,它就像是在乞丐家的儿子出生.....
type TPerson = class end;
下面这段就像是马斯克的儿子出生。。。
type TPerson = class(Tobject) end;
大家明白意思了吧?父亲那里有什么东西可以用的,儿子就有什么东西可以用,这就是继承(不是我们遗产继承的那种继承)。
然后呢,儿子们从父亲那里拿到了所有的东西,就开始作妖,自己又定义了一些自己的方法和属性,比如它用父亲的钱,做了一件花裤衩,这花裤衩是父亲们所没有的。这就叫派生。。。
最后大家来看一个人生赢家(它有五个爸爸):
type TPerson = class(Tobject,A,B,C,D) end;
9.深入了解类的属性:读取和写入
9.1.属性具有三个要素:
1.数据类型(type)
2.如何读取(Get)
3.如何写入(Set)
其中数据类型是每个属性都必须的,读和写按业务来选择.
我们来看下面的几个属性设置:
property name: string read Fname write SetFname; //数据类型:string, 读取数据时直接读Fname的值,在赋值时执行SetFname过程 property age: integer read GetFage ; //数据类型:integer , 读取数据时会执行GetFage函数,不能给age属性赋值,只读 property brithday: TDate read Fbrithday write Fbrithday; //数据类型:TDate , 读取数据时直接读Fbrithday 的值,赋值时,直接赋给Fbrithday ; 可读写
按下ctrl+shift+c,在private下面会自动添加这两行代码
procedure setFname(const Value: string); function getFage: integer;
同时也会在业务代码区,生成对应的过程或者函数框架.我们可以看到,set方法生成的是过程来给属性赋值,get方法生成的是函数,因为需要返回值 .
function TPerson.getFage: integer; begin end; procedure TPerson.setFname(const Value: string); begin
if value.trim.isempty then exit; //这里写一些你的业务代码
Fname := Value; end;
调用方式与上面讲的一样用就可以了.大家不要被这get和set迷惑,只要前期设置好业务逻辑就可以了.这两个家伙都是后台自动执行的,跟调用无关.
标签:end,Fname,yadang,Delphi,学类,小白来,TPerson,Fage,string 来源: https://www.cnblogs.com/yoooos/p/16480718.html