Class override question

Hi,

I have a question about class override: In the following code if super not called in derived class then base class’s task gets overwritten and only derived class task gets executed
BUT, if I call super from derived class, base class task gets executed and then derived class. Shouldnt set_type_override() overwrite the base class?

**
class base extends uvm_object;
  
  `uvm_object_utils(base)

  function new(string name= "base");
    super.new(name);
  endfunction
  
  virtual task cal;
    bit[31:0]  a;
    bit[31:0]  b;
    bit[31:0]  c;
    bit[31:0]  d;
    
    a = 20;
    b = 30;
    c = a +b;
    d = b-a;
    `uvm_info(get_type_name(), $sformatf("a %d b %d c%d",a,b,c), UVM_LOW);
    `uvm_info(get_type_name(), $sformatf("a %d b %d d%d",a,b,d), UVM_LOW);
    
    
  endtask
  
endclass

class derived extends base;
  
  `uvm_object_utils(derived)

  function new(string name= "derived");
    super.new(name);
  endfunction
  
  virtual task cal;
    bit[31:0]  a;
    bit[31:0]  b;
    bit[31:0]  c;
    
    super.cal();
    
    a = 10;
    b = 10;
    c = a +b;
    `uvm_info(get_type_name(), $sformatf("a %d b %d c%d",a,b,c), UVM_LOW);
    
    
  endtask
  
endclass

//In test class 
//function new
set_type_override("base", "derived");


//OUTPUT::
UVM_INFO testbench.sv(394) @ 0: reporter [derived] a         20 b         30 c        50
UVM_INFO testbench.sv(395) @ 0: reporter [derived] a         20 b         30 d        10
UVM_INFO testbench.sv(420) @ 0: reporter [derived] a         10 b         10 c        20
**

In reply to UVM_SV_101:

It’s working—that’s why you have three info messages printed. What may be confusing you is you are using the virtual method get_type_name() as the message ID. That always returns the “derived” class name. Try using type_name instead.

In reply to dave_59:

Hi Dave ,

Have some confusion with the Message ID . Here’s my understanding of the O/P , please correct me if wrong .

[I] Via get_type_name() as Message ID ::

Macro `uvm_object_utils inserts virtual function get_type_name() which returns
“base” and “derived” respectively .

Class derived essentially overrides virtual function get_type_name() defined in base class .

So when super.cal() is called with get_type_name() as Message ID , it’s equivalent
to this.get_type_name() .

As the base class function cal() is called via extended object ,
‘this’ points to extended object . Therefore this.get_type_name() returns “derived” .

Another way to look at it is that function get_type_name() in base class is
hidden from derived class ( as it’s overridden ) .

So get_type_name() in super.cal() calls the overridden function .

[II] Via type_name as Message ID ::

Since property can’t be overridden , “derived” class has 2 string property type_name ( one inherited , other defined in derived class )

So when super.cal() is called , as the inherited string property ( “base” ) is
nearest in the scope we observe “base” as Message ID in super.cal()
whereas as when control moves back to cal() in derived class , “derived” is
nearest scope . Hence the 3rd Message ID is “derived”