is 运算符执行动态类型检查,用来验证运行时一个对象的实际类型。object is class
as 运算符执行受检查的类型转换。object as classs
由于Sender代表了调用所在过程的控件,那么你就可以直接把它拿来当那个控件用
Self是指所编的程序范围是在哪一个类中,Delphi中大都在窗体范围内编程,因此,self即指窗体,如果在编写一个类或是一个组件,则self指该类或组件。
stored 指示字后面必须跟True、False、Boolean 类型的字段名或者一个返回Boolean 值的无参数方法。比如,
property Name: TComponentName read FName write SetName stored False;
若一个属性没有stored 指示字,就相当于指定了stored True。
default 指示字后面必须跟随一个和属性具有相同类型的常量,比如,
property Tag: Longint read FTag write FTag default 0;
要覆盖一个继承下来的默认值而不指定新值,使用nodefault 指示字。
default 和nodefault 只支持有序类型和集合类型(当它的基础类型是有序类型,并且上下边界都在0 到31 之间时)。
若声明属性时没有使用default 或者nodefault,它被当作nodefault 看待。对于实数、指针和字符串,
它们分别有隐含的默认值0、nil 和 ’ ’(空串)
很多时候会将一个Panel1放在Form1上,然后再将一个Button1放在Panel1上,这样的话,这个Button1的Owner就是Form1而Parent则是Panel1。
所有的Delphi的Component都有Owner 属性,Owner属性表示这个Component的所有者是谁,比如上面的例子,Button1的所有者(Owner )就是Form1,当Form1析构时,会先将Button1释放掉。也就是说,Owner会自动地控制Component的生命周期,它负责构件的创建和释放。如在上例中,系统默认Form上所有Component的所有者是Form1。顺便指出,Create方法应带有表示Component的Owner的参数.,如果Owner设置的为Nil值,那这个Component必须创建者编码析构它,Owner属性是只读的,并且在运行期是无法修改它的值。
类似,但不同于Owner属性,Parent 属性则表示Component从属于另一个Component,简单的说自身是其他Component的Child Component,例如 TForm,TGroupBox ,TPanel等。Parent是用来控制 在它的客户区范围内的Child Component,Parent决定如何展示包含的Child Component,例如:Left,Top等属性都是相对于Parent的位置。
Parent属性可以在运行期被修改。并非所有的Component都有Parent,Parent属性可以为Nil值,可以用HasParent 方法返回的Boolean值来判断Component是否拥有Parent。 我们可以设置Parent属性来做一些控制,例如:我们可以在Form1上置Panel1和Panel2,然后再放一个Button1在Panel1上,在Button1的OnClick事件中写上:Button1.Parent := Panel2; 运行这段代码你会发现,开始Button1是在Panel1上,然后按下Button1触发OnClick事件后,Button1‘跳’到了Panel2上。我们要在运行期间创建一个Button的话,就一定要注意指定它的Parent属性,否则Button不会显示出来,因为它必须拥有一个Parent的容器来显示自己。如果你在设计这个Button时察看下属性编辑器,你会看到ParentFont和ParentShowHint等属性,类似于这样的属性设置为True的话,就会使Button的Font以及ShowHint属性按Parent的Font和ShowHint的值来设置,保持一致的风格。比如Parent的Font是红色,那么Button的字体也将是红色。
ControlCount和ComponentCount的区别也就取决于Parent与Owner的区别,还是拿上面的例子解释下Panel1的ControlCount为1而ComponentCount却为0,是因为Button1的Parent属性指向的是Panel1而Owner属性则还是Form1,所以Form1的ComponentCount值才是1。我们可以利用Controls属性与Components属性去遍历Parent所包含的Child Component和Owner所管理的Child Component。还有一个区别就是ControlCount只包括可视的控件,而ComponentCount包括可视和不可视的控件。
type
IInterface = interface
['']
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
我们可以看到,和类的基本声明差不多,只是由关键字class改成了interface。
大家也许会注意到在紧跟在声明后的[''],这是什么呢?这是其实是接口的唯一标识,也就是我们说的TGUID;当把接口注册给系统后,我们可以通过注册表检索到00000000-0000-0000-C000-000000000046这样的键值。那么这就意味着,我们只需要知道一个TGUID的值就可以方便的访问这个接口。
当然,你可以在接口中定义其他的方法,但是Delphi中是不允许给接口添加变量成员的,因为接口是不允许有实现部分的。
同样,接口也可以继承、封装以及方法的覆盖。继承接口同类继承类似:
这里要注意一点,就是我们说过,接口的TGUID是每一个接口的唯一标识,那么也就是说,TGUID是不能重复的。你不能简单的从别处抄袭过来,那样是错误的。如果你需要一个TGUID,你可以在Delphi的代码编辑框中同时按下CTRL+SHIFT+G来获得一个新的TGUID值,这个值是Delphi为你自动生成的。
我们说了,接口只能有声明,不能有实现。那么怎么让接口为我们工作呢?
其实,接口的实现是需要借助于类来完成的(当然这看上去和C++中的多重继承的写法差不多)注意,既然接口是需要借助类来实现的,那么也就是说用来实现接口的类,必须实现接口中所有已定义的方法:
一般,我们用来实现接口的基类不会选TObject而会选TInterfacedObject,理由是TInterfacedObject类已经帮我们实现了IInterface接口中的方法,我们只需要实现我们自己接口中新的方法就可以了。
浙公网安备 33010602011771号