这个问题,总会弄混,这次把相关内容摘录出来,加深印象.
1.类的对象被定义的时候,只是一个空的句柄;当其构造函数被调用的时候,才分配空间,其句柄指向该片空间的入口地址;
2.派生类的对象被定义的时候,也只是一个空句柄,当构造函数
///////////////////////////////////////////////////////////////////////////////////////////////////
基类:
///////////////////////////////////////////////////////////////////////////////////////////////////
class Packet;
task build_payld();
$display("Packet payld");
endtask
task build_packet();
......
build_payld();
......
endtask
///////////////////////////////////////////////////////////////////////////////////////////////////
派生类:
///////////////////////////////////////////////////////////////////////////////////////////////////
class DerivedPacket extends Packet;
task build_payld();
$display("DerivedPacket payld");
endtask
endclass
///////////////////////////////////////////////////////////////////////////////////////////////////
测试代码:
///////////////////////////////////////////////////////////////////////////////////////////////////
module poly1;
DerivedPacket der=new();
initial der.build_packet();
endmodule
///////////////////////////////////////////////////////////////////////////////////////////////////
测试结果:
///////////////////////////////////////////////////////////////////////////////////////////////////
Packet payld
///////////////////////////////////////////////////////////////////////////////////////////////////
测试结果分析:
///////////////////////////////////////////////////////////////////////////////////////////////////
(1) 派生类对象在调用其build_packet过程中,会调用build_payld这个任务;而build_payld这个任务在父类扩展的过程中被重写过;
虽然这样,最终调用的build_payld仍是父类中的build_payld,而不是子类中的build_payld.
因为默认情况下,子类中重写的方法对于父类是不可见的.
(2) 派生类对象的空间分配分为两个部分,一部分来自父类的继承部分,一部分是重写或新增的部分.默认情况下,父类的方法是无法访问派生类的重写和新增部分的。假如希望重写的方法被父类看到,就需要依靠虚方法和多态.
(1) 类中的方法可以在定义的时候通过添加virtual关键字来声明一个虚方法,虚方法是一个基本的多态性结构.
(2) 虚方法为具体的实现提供一个原型,也就是在派生类中,重写该方法的时候必须采用一致的参数和返回值.
(3) 虚方法可以重写其所有基类中的方法,然而普通的方法被重写后只能在本身及其派生类中有效。
(4) 每个类的继承关系只有一个虚方法的实现,而且是在最后一个派生类中。
(5) 在P1指向P2后,当P1.printA被调用的时候,程序会调用访问内存中类对象P2中P1的部分,而此时发现printA是一个普通方法,为此直接调用并结束访问;
(6) 在P1指向P2后,当P1.printB被调用的时候,程序同样找到类对象P2中P1的部分,此时发现printB是个虚方法,这时其会咨询系统,查看整个P2在定义的时候是否重写了该方法.系统发现在P2中(除了P1外),确实重写了该方法,为此,程序会直接调用P2重写的实现.
(7) 带有虚方法的类称为多态类.