Delphi 面向对象编程 第二章

旧城冷巷雨未停 提交于 2020-05-08 19:40:54

类的声明是一种类型声明,在delphi中,类被当作一个类型来声明,语法为:

type class_name = class (base_class)

  {field }

  {procedure and function }

  {property }

end;

注意:1、类的声明可以在一个单元的interface或implement部分,但定义必须在implement下。

          2、在不指明base_class 的情况下,默认是TObject。

          3、数据成员必须在方法和属性之前。

数据(Field):在类中定义好的变量。

方法(procedure and function):类中封装的过程和函数,用于执行类的操作,反映的是行为而不是数据。

属性(property):访问对象数据的接口,即对类私有数据成员进行读写操作。

 

对象:类的实例化。一般使用构造函数create完成。基本语法:

    MyObject := TMyObject.Create();

一个类中可以不止一种构造函数,delphi不自动调用,需要程序员自己调用。

类的操作符:

1、is :用于判定对象的类而不是对象本身。语法:class_variable is class_name;

2、as :把一个对象变量的类型转换成另一类的类型或者把一个接口变量转换成另一接口类型。class_variable as class_name.

(所转换的对象变量的类型必须和目标类型有直接或间接的继承关系,否则会不兼容。)

3、self:在普通方法中,是对象的引用,在类方法中,则是类的引用。self 主要用于如下情况:a、如果在方法中调用另一个对象的方法时候,需要将自身的参数传递过去,直接使用self;b、如果派生类和基类出现了数据成员重名,想要访问基类的数据成员,而每次只能得到派生类本身的数据成员,可使用强制转换 base_class(seft).variable_name;c、方法内调用了与数据成员同名的局部变量,使用变量名可访问局部变量,使用self.varaiable_name 可访问到数据成员。


方法 :在类中定义,应用与特定类和其祖先类的对象,含有一个隐含参数self,引用作为方法调用主体的对象。注意:在类方法中,只引用类而不是对象。

1、普通方法: 在类内定义,单元内实现,可设置保护方式。语法如下:

     定义:type class_name  = class (base_class)

                   {可见性限定符}

                    private

                    ...

                    {或public}

                    procedure method_name (<parameters list>);

                    function function_name(<parameters list>) : return_type;

                end;

      实现:procedure class_name.method_name(<parameters list>);

                begin

                  {语句块;}

                end;

 注意:在一般方法的实现中,最好只访问自己类的成员,不要范围类外的对象,防止对象未创建而发生保护性错误。

2、构造方法:用于创建对象,并初始化类成员。其返回是一个对象的引用。

定义: type class_name = class (base_class)

               ...

               constructor name(<parameter list>);

            end;

实现:constructor class_name.name(<parameter list>);

          begin

              ...

          end;

调用创建实例:class_instance := class_name.name(<parameter list>);

注意:构造方法不是必须的,如果不声明,默认调用父类的,如果不想扩充基类构造函数,则可不声明。一旦构造函数调用失败,程序仍然执行,就会因访问出现保护性错误。

3、析构方法:用于销毁对象及其数据。语法:

声明:type class_name = class(base_class)

              ...

             destructor function_name ();

          end;

定义:destory class_name.function_name();

调用:class_variable.function_name();

注意:类的构造方法可以不止一个,建议覆盖继承下来的析构函数,并不在声明其他析构函数:destructor destory;override;

不要在程序中调用destory 销毁对象,而用free;析构的顺序:先自身,后继承类的:

    destructor class_name.destory;

    begin

         ...{free,close}

        inherited destory;

    end;

4、类方法:作用于类而不是对象上的方法,但可以通过对象调用哪个,也可以为类引用。语法:

声明:class procedure [function ]  name (<parameter list>);

调用:class_name. function_name(<parameter list>);  

5、消息处理方法:用于响应动态分配的消息。语法:

定义:procedure name(<parameters list>);message message_id;

 

方法绑定机制:建立方法调用和方法本体之间的联系。

1、静态方法:运行信息静态链接到可执行文件,速度快,但不支持覆盖。

2、虚方法和动态方法:声明的关键字:virtual和dynamic。能在派生类中被覆盖,其调用有类和对象的实际类型决定。编译器事先不知道方法的地址,通过VMT或DMT寻找运行时的函数地址。VMT还存有祖先的所有虚方法,占内存多,但速度快。DMT仅有它声明的方法,但需要祖先的DMT才能访问到,占内存少,但速度慢。

3、抽象方法:在所声明的类中暂时不实现,而有其派生类实现的虚方法或动态方法,需在virtual或dynamic后使用abstract。如果派生类不实现此法,可忽略或者override和abstract 来声明。

4、方法的覆盖、隐藏和重载:

覆盖:使一个方法在不同的派生类中表现不同的行为,可实现OOP的多态性。但被覆盖的方法仅限于以virtual 和dynamic声明的方法,为覆盖这些方法,需要override 代替virtual 和dynamic。如果在派生类中用virtual 和dynamic 重新声明祖先的同名方法,则是建立新的方法。

隐藏:如果派生类中声明的方法和祖先同名,但又没有使用override,则祖先的方法被隐藏,此时派生类中两个方法都存在,方法名却是静态绑定的。注意,编译器会因派生方法覆盖祖先同名方法而在编译时发出警告,此时,可以使用reintoduce指示符解决。

重载:一个方法可以使用overload 限定符来重新声明,这样函数可以和祖先的函数同名,依靠参数来决定调用情况。如果要重载一个虚方法,则需要在重新声明时使用reintroduce限定符。

 

可见性:用于保护类成员。在缺省情况下,类成员的可见性是public(在{$M+}状态下,是published)

private : 成员仅在该类的方法中被访问,它的派生类和实例都无法访问,但delphi的private却不是严格的,只要同一个单元中的类,都可以访问其他类的私有成员。

protected:只有在派生类的实现中才应用的成员通常使用protected属性。

public:是完全可以访问的成员,可见性最大,在设计中应该保持其成员的简明,并尽早使之稳定。

published:可见性和public相同,但其会产生RTTI,RTTI是应用程序能够动态查询一个对象的数据成员和属性,也能够定位它的方法。可公布属性和数据类型是受限的。同时,一个类不能使用相同的名字公布两个或两个以上的被重载的方法,只有当数据成员属于类或接口类型时,它才是可公布的.

属性 : 它像一个数据成员,但数据成员仅仅是一个存储位置,属性则通过关联特定的过程和函数,保证了对其读写是安全和可控的.

声明:property property_name [index] : type index integerConstant specifiers;(specifiers 是由read,write,stored,defalut和implement等组成,每个属性至少含有一个read或者write)。

//TO DO Tomorrow night

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!