看产生的汇编吗可以看到对于H1.ShowInf是这样的
mov eax,ebx //ebx为该对象的地址
mov edx,[eax]
call dword ptr [edx]而对于TWorker(H1).ShowInfo
mov eax,ebx
call TWorker.ShowInfo所以就是这样的
可以在TWorker.ShowInfo这样
Writeln('调用TWorker.ShowInfo' + '(' + self.ClassName +')');
就可以看出点意思了
mov eax,ebx //ebx为该对象的地址
mov edx,[eax]
call dword ptr [edx]而对于TWorker(H1).ShowInfo
mov eax,ebx
call TWorker.ShowInfo所以就是这样的
可以在TWorker.ShowInfo这样
Writeln('调用TWorker.ShowInfo' + '(' + self.ClassName +')');
就可以看出点意思了
能说得明白点吗
这个例子本来写出来是和别人讲解多态的,但是这个结果实在是让我不懂.
当TWorker(H1)时,H1本身就是一个地址,转换为TWorker类型,相当于调用TWORKER_SHOWINFO(TWorker(H1));当然可以调用,当如果TWorker中有一些数据成员的话,并且
调用ShowInfo访问了这些成员,就会访问到错误的值,因为在此时Self指向的是TStudent空间以上个人理解,说错莫怪
我在java里面测试的话,类似的动作是会有运行时错误的。
如果用H1 as TWorker则肯定会出错,
其实这本身也没有什么荒不荒谬的
类中的函数本身被名字分裂为一个函数,相当于一静态函数调用
不要把这些函数想象为占据该类的内存快内,一个对象所占有的内存空间就是
它所拥有的VPTR和一些数据成员
无论是对于调用TWoker对象的ShowInfo还是Student对象转为TWorker类型的
ShowInfo,汇编码都是如此
mov eax,ebx
call TWorker.ShowInfoeax即为对象的地址,也即为Self值
所以ShowInfo输出ClassName时
对于TWorker(H1)而言为TStudent
对于真正的TWorker,就为TWorker这是我的理解,继续讨论,呵呵