SV/UVM 类的多态和虚方法解析

        类具有三大特性:封装/继承/多态,多态是面对对象编程中最神奇的特征,也是最抽象和难以理解的特征。对于初学者来说,最好对sv有了一定了解,在掌握了封装和继承之后再学习多态会更容易理解。

1.类的继承

        首先复习一下继承的概念:继承是利用共性构建一个基类(父类),在此基础上将问题分类,不同的分类具有各自的共性,使用这些分类的共性构建一个派生类(子类)。

class bird extends animal;
function new();
 super.new();
 category = "bird";
endfunction
endclass

        继承的优点在于方便,子类从父类派生后天然具有父类所有特征:父类的成员变量也是子类的成员变量,父类的成员函数也是子类的成员函数。当然,子类也可以自己定义额外的成员变量和系统函数。

        需要注意的是,如果父类中某成员类型是local,那么子类也不可以对其访问。local类型变量只有当前类可以访问,protected类型变量可以供父类子类访问而不被外部访问。

2.类的多态

        假设animal中存在函数:

class animal;
 function void print_hometown();
 $display("my hometown is earth!");
 endfunction
endclass

        同时在bird和nobird类中也有自己的函数:

class bird extends animal;
 function void print_homwtown();
 $display("my hometown is sky!");
 endfunction
endclass


class nobird extends animal;
 function void print_homwtown();
 $display("my hometown is land!");
 endfunction
endclass

现在有一个名字为print_animal的函数:

function automatic void print_animal(animal p_animal);
 p_animal.print();
 p_animal.print_hometown();
endfunction

该函数的参数是一个animal类型的指针,如果我们实例化一个bird,并传递给函数,当然是完全可以的:

initial begin
 bird members[20];
 members[0] = new();
 members[0].init("parrot",20091021,"bird",20,1);
 print_animal(members[0]);
end

但是这样打印出来的结果会是“my hometown is earth”,而不是希望的“my hometown is sky”。为了得到想要的结果,我们可以进行类型转换:

function automatic void print_animal2(animal p_animal);
 bird p_bird;
 nobird p_nbird;
 p_animal.print();
 if($cast(p_bird,p_animal))
   p_bird.print_hometown();
 else if($cast(p_nbird,p_animal))
   p_nbird.print_hometown();
endfunction

        从父类向子类的类型转换需要通过cast系统函数进行,但是反过来子类向父类的类型转换可以自动完成,如调用print_animal时,members[0]是bird类型,系统自动将其转成animal类。这种做法虽然实现了目标,但是非常冗余复杂,并且不具备可重复性,如果有更多类型,岂不是需要一个一个进行定义,修改函数非常麻烦。那么有什么办法可以自动解决呢?

3.虚函数

        答案就是虚函数,在定义函数前只需要在前面加上virtual关键字:

class animal;
 virtual function void print_hometown2();
 $display("my hometown is earth!");
 endfunction
endclass

class bird extends animal;
 virtual function void print_hometown2();
 $display("my hometown is sky!");
 endfunction
endclass

class nobird extends animal;
 virtual function void print_hometown2();
 $display("my hometown is land!");
 endfunction
endclass

在print_animal3中调用该函数:

function automatic void print_animal3(animal p_animal);
 p_animal.print();
 p_animal.print_hometown2();
endfunction

        在initial语句中将members[0]传递给此函数后,打印出来的结果就变成了我们想要的“my hometown is sky”。同理如果实例化一个nobird,结果就会变成“my hometown is land”在print_animal3中,调用同样的函数,输出了不同的结果,表现出了不同形态,这就是多态。而多态的实现需要依赖虚函数。

  • 54
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值