重载的目的:节省类中的命名资源和提高代码的可读性。
重载是发生在一个类中,
1、方法名相同
2、方法的参数不同(参数个数或者参数类型)
3、方法的返回值类型不影响重载
( 当两个方法的名字相同,参数也相同,但是返回值不同的时候,不构成重载 )
class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
int ret = add(a, b);
System.out.println("ret = " + ret);
}
public static int add(int x, int y) {
return x + y;
}
public static double add(int x, int y) {
return x + y;
}
}
//这里两个add 的参数相同,返回值类型不同,构成重载
重写是指 子类实现父类的同名方法,方法参数和返回值类型都完全相同;
重写发生在子类和父类之间,也就是说重写不是在同一个类里面;
在子类继承父类时,子类的方法和父类的方法相同(访问修饰限制符,返回值类型,方法名,参数列表),方法体不同,这种子类的方法将父类的方法覆盖叫做重写;
class Animal {
public void eat(String food) {
...
}
}
class Bird extends Animal {
@Override
public void eat(String food) {
...
}
}
//这里 Bird中的 eat 对 Animal 中的eat 进行重写
//在父子类的继承中有相同的方法,唯一不同就是方法体,
//一般是父类的该方法满足不了子类的需求所以才发生重写。
注意:
1. 重写和重载完全不一样,不要混淆
2. 普通方法可以重写,static 修饰的静态方法不能重写
3. 重写中子类的方法的访问权限不能低于父类的方法访问权限
重载和重写的区别总结如下表:
N | 区别 | 重载 | 重写 |
---|---|---|---|
1 | 概念 | 方法名称相同,参数的类型及个数不同 | 方法名称、返回值类型、参数的类型及个数完全相同 |
2 | 范围 | 一个类 | 继承关系 |
3 | 限制 | 没有权限要求 | 被重写的方法不能拥有比父类更严格的访问控制权限 |
再回到我们的 systemverilog ,之前有提到过关于方法加 virtual 修饰的问题,简而言之就是在 子类中对父类中的方法进行 重写,加不加 virtual 修饰的区别在前面已经有过说明;
而对于 phase 而言,每个 component 的 phase 都是对 uvm_component 的phase 的重写,而且在 uvm_component 中都加了 virtual 修饰,所以至少在 方法 这个层次sv中不存在重载只存在重写(override)!!如下会报错:
class A;
virtual function int dis(string str="A");
$display("this is %s",str);
dis=1;
endfunction
endclass
class B extends A;
function void dis(); // 只有函数名相同,参数不同
$display("this is B");
endfunction
endclass
多说一句,好像在 uvm_primer 中有写到过对 new 进行重载的说法,这一点留待后续讨论!!