其他分享
首页 > 其他分享> > Delphi 小白来学类

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