首先,我们知道多态是面向对象的三大特性之一。所谓多态,其思想就是,对于不同的具体类型,我们可以通过相同的抽象接口进行访问,而不必关系具体类型的实现细节。就像下达通知:所有员工明天9点在人民广场集合。并不需要具体通知每个住在不同位置的人应该几点出发,走什么路线,因为这是具体的人的责任,而非通知下达者的责任。所以,在写到需要判断ClassName进行分别处理的时候,首先应该想到的处理方式是在父类中增加接口,通过子类override完成。如下面改变把图形大小的代码: for i := 0 to 图形列表.Count - 1 do begin 图形 := 图形列表[i]; if 图形.ClassName = ''''长方形'''' then begin 长方形(图形).长 := 长方形(图形).长 * 2; 长方形(图形).宽 := 长方形(图形).宽 * 2; end else if 图形.ClassName = ''''圆形'''' then begin 圆形(图形).半径 := 长方形(图形).半径 * 2; end end;
就可以在父类“图形”中增加“ChangeSize”方法,代码如下 图形 = class …… procedure ChangeSize(rate: Integer); virtual; end;
长方形 = class …… procedure ChangeSize(rate: Integer); override; end;
procedure 圆形.ChangeSize(rate: Integer); begin 半径 := 半径 * rate; end; 这样修改后,上面的代码就可以这样调用了: for i := 0 to 图形列表.Count - 1 do begin 图形 := 图形列表[i]; 图形.ChangeSize(2); end; 这样代码的意图清晰了很多。
其次如果被判断的对象有可能为空,使用ClassName判断必须先判断对象是否赋值,否则就会出现内存访问错误。判断代表必须写为:if Assigned(aObject) and aObject.ClassName = ''''TClass1'''';而采用is只需要写为if aObject is TClass1。 最后一个不采用ClassName作为判定的原因是,ClassName只是用来描述一个类的属性,字符串比较不能在编译期获得检查,如果存在拼写错误,或是大小写问题代码都会出现逻辑错误,而这种错误只有在运行期运行到这一语句的时候才会被发现。 if aControl.ClassName = ''''TEidt'''' then //只有在你注意到Edit没有初试化时才会来检查这段代码; if aControl is TEidt then //无法编译通过;