一、override 重载 type TFigure = class procedure Draw; virtual;//(我的理解是)父类中可以使用父类的,子类中使用子类的。与“四”是有区别的。 end; TRectangle = class(TFigure) procedure Draw; override;//a1 end; TEllipse = class(TFigure) procedure Draw; override;//a2 end; 使用 var Figure: TFigure; begin Figure := TRectangle.Create; Figure.Draw; // 执行a1 Figure.Destroy; Figure := TEllipse.Create; Figure.Draw; // 执行a2 end; 二、overload 多态 procedure foo(i: integer); overload; procedure foo(d: double); overload; procedure foo(v: variant); overload; 典型用法。如果是对于继承的。必须使用reintroduce type T1 = class(TObject) procedure Test(I: Integer); overload; virtual; end; T2 = class(T1) procedure Test(S: string); reintroduce; overload; end; ... SomeObject := T2.Create; SomeObject.Test('Hello!'); // T2.Test SomeObject.Test(7); // T1.Test 三、override & inherited override是用来重载父类的procedure, 如果父类是virtual 或者 dynamic 方法的,就可以使用inherited,来调用父类中的代码。 四、abstract procedure DoSomething; virtual; abstract;//如果是这个样式的,表示要在子类中实现(代码)。而父类中,其他procedure function可以使用这个procedure。 (这里的virtual似乎不能被dynamic替换)。 使用procedure DoSomething; virtual; abstract;和procedure DoSomething; virtual;的区别就是,前者的实现代码在子类,而后者实现代码在自身。后者可以在子类中override一下,使其子类也有自己的实现代码。 2009-4-11 在最近的代码中发现(不知道是不是D7的缘故) procedure DoSomething; virtual; abstract; procedure DoSomething; dynamic; abstract; 都是可以的。 而且在继承类中也可以不写实现代码。 在基类中如果要判断有没有被继承类写实现代码的方式不是 if Assigned(DoSomething) then ... 而是 if MethodAddress('DoSomething')<>nil then... 五、reintroduce 覆盖父类中的virtual 方式的内容。(编译器不会提示“xxx 被hide了”) 六、static 默认就是这个。 我们常打 procedure test(xx:Integer);其实就是static的。 这个比较好理解。 如果子类中,声明了一个test,跟父类无关。各自用各自的。 除非使用强制转换。比如: type TFigure = class procedure Draw; end; TRectangle = class(TFigure) procedure Draw; end; //实现 var Figure: TFigure; Rectangle: TRectangle; begin Figure := TFigure.Create; Figure.Draw; // 父类用父类的 TFigure.Draw Figure.Destroy; Figure := TRectangle.Create; Figure.Draw; // 虽然初始化为子类,但是由于申明的是父类,所以Figure还是调用了父类的Draw TFigure.Draw TRectangle(Figure).Draw; // 强制转换成子类,就可以用TRectangle.Draw Figure.Destroy; Rectangle := TRectangle.Create; Rectangle.Draw; // 子类用子类的 TRectangle.Draw Rectangle.Destroy; end; 七、forward declaration提前定义。 用于类被提前使用。注意fd的class后面要立即加“;”不能使用括号和基类。 type TFigure = class; // forward declaration TDrawing = class Figure: TFigure; ... end; TFigure = class // defining declaration Drawing: TDrawing; ... end; 八、virtual 和 dynamic 虚拟方法占用的内存大,调用速度快;动态方法相反。 如今,哪有PC内存不够的。 所以,笔者建议,就使用virtual吧。 2009-04-07 我知道了,内存是有不够用的时候。 所以这里修改说法,需要来回调用的用virtual,一般只用到1,2次的用dynamic。 像笔者一般写一个基类函数,只用一次,所以大部分都改成dynamic了。 但是有个地方必须要用virtual private FItem:Integer procedure SetItem(Value:Integer);virtual;//dynamic不允许 public property Item:Integer;read FItem write SetItem; end;