其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

Delphi中避免使用ClassName判断对象的类型


发布日期:2020年12月19日
 
Delphi中避免使用ClassName判断对象的类型
首先我们知道多态是面向对象的三大特性之一所谓多态其思想就是对于不同的具体类型我们可以通过相同的抽象接口进行访问而不必关系具体类型的实现细节就像下达通知所有员工明天点在人民广场集合并不需要具体通知每个住在不同位置的人应该几点出发走什么路线因为这是具体的人的责任而非通知下达者的责任所以在写到需要判断ClassName进行分别处理的时候首先应该想到的处理方式是在父类中增加接口通过子类override完成如下面改变把图形大小的代码

for i := to 图形列表Count do

begin

图形 := 图形列表[i];

if 图形ClassName = 长方形 then

begin

长方形(图形)长 := 长方形(图形)长 * ;

长方形(图形)宽 := 长方形(图形)宽 * ;

end

else if 图形ClassName = 圆形 then

begin

圆形(图形)半径 := 长方形(图形)半径 * ;

end

end;

就可以在父类图形中增加ChangeSize方法代码如下

图形 = class

……

procedure ChangeSize(rate: Integer); virtual;

end;

长方形 = class

……

procedure ChangeSize(rate: Integer); override;

end;

圆形 = class

……

procedure ChangeSize(rate: Integer); override;

end;

在具体的图形类中实现大小改变的代码

procedure 长方形ChangeSize(rate: Integer);

begin

长 := 长 * rate;

宽 := 宽 * rate;

end;

procedure 圆形ChangeSize(rate: Integer);

begin

半径 := 半径 * rate;

end;

这样修改后上面的代码就可以这样调用了

for i := to 图形列表Count do

begin

图形 := 图形列表[i];

图形ChangeSize();

end;

这样代码的意图清晰了很多

当然在很多时候出现判断ClassName的情况下并不能采用上边的解决方法比如遍历Form的Cotrols并对不同的控件进行分别初试化我们不可能去TControl中增加初始化方法只有采用判别具体子类类型那么这时我推荐采用is运算符而非直接比较ClassName

is的用法语句 aObject is TForm 在不同的aObject的类型情况下结果如下

aObject是TObject结果为假

aObject是TForm结果为真

aObject是TForm结果为真

aObject是TEdit结果为假

aObject是nil结果为假

从上面示例可以看到采用is的一个优点is可以判断是否子类的情况比如我们在初始化控件的时候根据是TImage还是TEdit作不同的初始化通过is判断处理将来也许会采用TCoolEdit来美化界面那么这段代码不需要更改因为一个TCoolEdit是一个TEdit而如果采用ClassName那么必须更改为子类的名字才行

其次如果被判断的对象有可能为空使用ClassName判断必须先判断对象是否赋值否则就会出现内存访问错误判断代表必须写为if Assigned(aObject) and aObjectClassName = TClass而采用is只需要写为if aObject is TClass

最后一个不采用ClassName作为判定的原因是ClassName只是用来描述一个类的属性字符串比较不能在编译期获得检查如果存在拼写错误或是大小写问题代码都会出现逻辑错误而这种错误只有在运行期运行到这一语句的时候才会被发现

if aControlClassName = TEidt then //只有在你注意到Edit没有初试化时才会来检查这段代码

if aControl is TEidt then //无法编译通过

综合上面所述在需要判定一个对象的具体类型时首先应该考虑通过多态处理避免这种分别特殊处理的语句实在不能避免的情况下应该采用is运算符判断而非ClassName

在一种很特殊的情况下is可能不能得到想要的结果比如需要分别处理TEdit和TCoolEdit的情况用is的话CoolEdit也会判断为TEdit这时可以采用ClassType方法也要胜过没有类型检测的字符串比较

aCoolEdit is TEdit //True;

aCoolEditClassType = TEdit//False;

aCoolEditClassType = TCoolEdit//True;               

上一篇:用Delphi2005学设计模式之简单工厂篇

下一篇:20080826 - Delphi 2009 来了