虚方法使用virtual限定符,动态方法使用dynamic限定符,无论是virtual限定符还是dynamic限定符均表示在基类中声明了一个虚方法,其目的是为了派生类能够覆盖该方法,实现多态.这两个限定符的语义是相同的,惟一不同的是,它们产的实现方法和调用方法,这涉及到Delphi的编译机制.
Delphi的编译器会自动维护用于添加虚方法的虚方法表(VMT)和用于添加动态方法的动态方法表(DMT).
虚方法表存放的是类及其基灶声明的所有虚方法的指针.每一个类都具有一个惟一的VMT,每一个类或其祖类的虚方法在VMT中都有一个入口.无论一个类是否有自己定义的虚方法,只要它继承了祖先类的虚方法,它也会有自己的VMT,列出它继承的所有虚方法.因为每一个类都有一个自己的VMT,Delphi就可以使用VMT来识别一个类,实际上,一个类引用就是指向类的VMT的指针,调用classtype方法则返回指向VMT的指针.
由于基类和派生类的VMT之间过强的关联性,因此派生类继承了祖先类的虚方法,也就是说派生类的VMT的前面一部分必须与基类相同.而当基类和派生类不在同一个DLL或EXE中的时候,这个要求是很难满足的.基类一旦改变,派生类如果不重新编译,就将导致错误.另外,如果类的层次很深,比如要建一个有数百个类的大型框架,此时VMT将会因不断继承的虚方法而变得非常庞大,导致效率不高.
为了解决这个问题,Delphi提供了一个DMT的机制.每一个类的DMT中只维护部分的动态方法,也就是说DMT仅列出了该类所声明的动态方法,它并不包括从祖先类那里继承来的方法.
虽然dynamic方法解决了virtual的方法问题,但是也付出了不小的代价:时间效率和可读性,因此也决定了该方案的应用面一广.大多数情况下使用virtual方法要比dynamic方法快,占用内存少.